[PATCH v7 14/14] KVM: s390: Fix kvm_arch_commit_memory_region() when low on memory

From: Claudio Imbrenda

Date: Fri Jul 31 2026 - 09:08:28 EST


When low on memory, kvm_arch_commit_memory_region() might not perform
the required action completely, and instead just print a warning and
return. This allows the VM to continue running with an inconsistent
state.

Fix by refilling the struct kvm_s390_mmu_cache and trying again. A true
failure only happens if the refill fails, or if the cache cannot be
allocated at all; in such case print a warning and kill the VM. Such a
failure cannot currently happen.

Signed-off-by: Claudio Imbrenda <imbrenda@xxxxxxxxxxxxx>
Fixes: e38c884df921 ("KVM: s390: Switch to new gmap")
---
arch/s390/kvm/kvm-s390.c | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 518a69c55e85..fd8badb0d571 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -5830,7 +5830,7 @@ void kvm_arch_commit_memory_region(struct kvm *kvm,
{
const struct dat_walk_ops ops = { .pte_entry = cmma_d_count_pte, };
struct kvm_s390_mmu_cache *mc __free(kvm_s390_mmu_cache) = NULL;
- int rc = 0;
+ int rc = -ENOMEM;

guard(mutex)(&kvm->slots_arch_lock);

@@ -5838,11 +5838,9 @@ void kvm_arch_commit_memory_region(struct kvm *kvm,
return;

mc = kvm_s390_new_mmu_cache();
- if (!mc) {
- rc = -ENOMEM;
+ if (!mc)
goto out;
- }
-
+retry:
scoped_guard(write_lock, &kvm->mmu_lock) {
if (kvm->arch.migration_mode && kvm->arch.use_cmma && old) {
_dat_walk_gfn_range(old->base_gfn, old->base_gfn + old->npages,
@@ -5865,9 +5863,15 @@ void kvm_arch_commit_memory_region(struct kvm *kvm,
case KVM_MR_FLAGS_ONLY:
break;
default:
+ rc = 0;
WARN(1, "Unknown KVM MR CHANGE: %d\n", change);
}
}
+ if (rc == -ENOMEM) {
+ rc = kvm_s390_mmu_cache_topup(mc);
+ if (!rc)
+ goto retry;
+ }
out:
if (rc)
pr_warn("failed to commit memory region\n");
--
2.55.0