When ESSA is executed in the guest for the first time, allocate all page tables and split all existing large page mappings, regardless of the hpage parameter. With the page tables present (even if all the entries within are not present), ESSA will not cause page faults. Without this fix, ESSA will cause a fault on the first page of each segment (1M block). If userspace is backing the guest with huge pages (hugetlbfs or THP), the page fault will be resolved by faulting in the whole huge page. The result is that at startup the whole guest memory is faulted in, since the guest will mark all of its memory at boot. With this fix, no extra guest memory is allocated. This will also prevent the first page in each segment from being faulted in, regardless of hugepages. Fixes: e38c884df921 ("KVM: s390: Switch to new gmap") Signed-off-by: Claudio Imbrenda --- arch/s390/kvm/s390/priv.c | 8 ++++---- arch/s390/kvm/s390/s390.c | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/s390/kvm/s390/priv.c b/arch/s390/kvm/s390/priv.c index 856939acf012..f7f49c2338b6 100644 --- a/arch/s390/kvm/s390/priv.c +++ b/arch/s390/kvm/s390/priv.c @@ -1241,14 +1241,14 @@ static int handle_essa(struct kvm_vcpu *vcpu) 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 - * a migration. Enable CMMA in the mm_context. - * Since we need to take a write lock to write to the context + * the SIE block and in the gmap, and we are not doing a + * migration. Enable CMMA in the gmap. + * Since we need to take a mutex to write to the gmap * to avoid races with storage keys handling, we check if the * value really needs to be written to; if the value is * already correct, we do nothing and avoid the lock. */ - set_bit(GMAP_FLAG_USES_CMM, &vcpu->arch.gmap->flags); + gmap_enable_cmm(vcpu->arch.mc, vcpu->arch.gmap); /* * If we are here, we are supposed to have CMMA enabled in * the SIE block. Enabling CMMA works on a per-CPU basis, diff --git a/arch/s390/kvm/s390/s390.c b/arch/s390/kvm/s390/s390.c index 18fb200f854a..23be83c0c0d8 100644 --- a/arch/s390/kvm/s390/s390.c +++ b/arch/s390/kvm/s390/s390.c @@ -2349,6 +2349,8 @@ static int kvm_s390_set_cmma_bits(struct kvm *kvm, if (r) return -EFAULT; + gmap_enable_cmm_already_locked(mc, kvm->arch.gmap); + do { r = kvm_s390_mmu_cache_topup(mc); if (r) @@ -2359,8 +2361,6 @@ static int kvm_s390_set_cmma_bits(struct kvm *kvm, } } while (r == -ENOMEM); - set_bit(GMAP_FLAG_USES_CMM, &kvm->arch.gmap->flags); - return r <= 0 ? r : -EFAULT; } -- 2.56.0