Kernel KVM virtualization development
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Claudio Imbrenda" <imbrenda@linux.ibm.com>, kvm@vger.kernel.org
Cc: linux-s390@vger.kernel.org, "Heiko Carstens" <hca@linux.ibm.com>,
	"Vasily Gorbik" <gor@linux.ibm.com>,
	"Alexander Gordeev" <agordeev@linux.ibm.com>,
	"Christian Borntraeger" <borntraeger@linux.ibm.com>
Subject: Re: [PATCH v4 6/7] KVM: s390: Introduce gmap_allocate_all_page_tables_best_effort()
Date: Wed, 28 Oct 2026 19:10:12 +0000	[thread overview]
Message-ID: <sashiko-outbox-188342@kernel.org> (raw)
In-Reply-To: <20261028185422.272146-7-imbrenda@linux.ibm.com>

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] kvm: s390: pass DAT_WALK_USES_SKEYS to dat_entry_walk() on split
- [Low] kvm: s390: use return on kvm_s390_mmu_cache_topup() failure
--

commit 9e76b2f0d91bb75ee34f562ce5400b323e47a284
Author: Claudio Imbrenda <imbrenda@linux.ibm.com>

KVM: s390: Introduce gmap_allocate_all_page_tables_best_effort()

This commit introduces gmap_allocate_all_page_tables_best_effort() to
walk all memslots of a running guest and allocate 4K page tables while
splitting existing large page mappings on a best-effort basis.

> diff --git a/arch/s390/kvm/gmap/gmap.c b/arch/s390/kvm/gmap/gmap.c
> index 04f3ab03a041a..3ff08232cbb36 100644
> --- a/arch/s390/kvm/gmap/gmap.c
> +++ b/arch/s390/kvm/gmap/gmap.c
> @@ -1524,3 +1524,40 @@ struct gmap *gmap_create_shadow(struct kvm_s390_mmu_cache *mc, struct gmap *pare
>  	}
>  	return new;
>  }
> +
> +/* Bail out for any allocation failure. This is only a best effort to allocate all page tables. */
> +void gmap_allocate_all_page_tables_best_effort(struct gmap *gmap)
> +{
> +	struct kvm_s390_mmu_cache *mc __free(kvm_s390_mmu_cache) = NULL;
> +	struct kvm_memory_slot *ms;
> +	struct kvm_memslots *slots;
> +	gfn_t gfn, start, end;
> +	union crste *crstep;
> +	union pte *ptep;
> +	int bkt;
> +
> +	mc = kvm_s390_new_mmu_cache();
> +	if (!mc)
> +		return;
> +
> +	guard(srcu)(&gmap->kvm->srcu);
> +
> +	slots = kvm_memslots(gmap->kvm);
> +	if (!slots || kvm_memslots_empty(slots))
> +		return;
> +
> +	kvm_for_each_memslot(ms, bkt, slots) {
> +		start = ALIGN(ms->base_gfn, _PAGE_ENTRIES);
> +		end = ALIGN_DOWN(ms->base_gfn + ms->npages, _PAGE_ENTRIES);
> +
> +		for (gfn = start; gfn < end; gfn += _PAGE_ENTRIES) {
> +			if (kvm_s390_mmu_cache_topup(mc))
> +				break;

[Severity: Low]
Should this be a return instead of break?

Using break here only exits the inner GFN loop for the current memslot,
so kvm_for_each_memslot() will continue iterating over any remaining
memslots and retrying allocations after kvm_s390_mmu_cache_topup(mc) has
failed.

> +
> +			guard(write_lock)(&gmap->kvm->mmu_lock);
> +
> +			dat_entry_walk(mc, gfn, gmap->asce, DAT_WALK_ALLOC | DAT_WALK_SPLIT,
> +				       TABLE_TYPE_PAGE_TABLE, &crstep, &ptep);

[Severity: High]
Can splitting an aged large page here lose guest storage keys when
uses_skeys(gmap) is true?

When a 1M or 2G large page is aged via gmap_age_gfn() ->
gmap_clear_young_crste(), the entry is marked invalid (h.i = 1) while
the guest storage keys for its 4K frames remain in hardware storage keys.

When dat_entry_walk() splits that invalid large PMD via dat_split_ste(),
saving the hardware storage keys into the newly allocated 4K PGSTEs is
gated on uses_skeys (from DAT_WALK_USES_SKEYS):

arch/s390/kvm/gmap/dat.c:dat_split_ste() {
    ...
			pgste_init.pcl = uses_skeys && init.h.i;
			dat_init_pgstes(pt, pgste_init.val);
		} else {
			dat_init_page_table(pt, init.val, 0);
		}

		if (dat_pmdp_xchg_atomic(pmdp, old, new, gfn, asce)) {
			if (!pgste_init.pcl)
				return 0;
			for (i = 0; i < _PAGE_ENTRIES; i++) {
				union pgste pgste = pt->pgstes[i];

				pgste = dat_save_storage_key_into_pgste(pt->ptes[i], pgste);
				pgste_set_unlock(pt->ptes + i, pgste);
			}
    ...
}

Because DAT_WALK_USES_SKEYS is not passed to dat_entry_walk(),
pgste_init.pcl is false and the new PGSTEs are left zeroed while the new
PTEs have h.i = 1. When a subsequent minor fault validates the PTE via
_gmap_handle_minor_pte_fault() -> gmap_ptep_xchg() -> __dat_ptep_xchg(),
uses_skeys(gmap) is true, so __dat_ptep_xchg() restores the zeroed PGSTE
over the hardware storage key:

arch/s390/kvm/gmap/dat.c:__dat_ptep_xchg() {
    ...
	if (uses_skeys) {
		if (old.h.i && !new.h.i)
			/* Invalid to valid: restore storage keys from PGSTE. */
			dat_set_storage_key_from_pgste(new, pgste);
    ...
}

Should this pass (uses_skeys(gmap) ? DAT_WALK_USES_SKEYS : 0) in the
dat_entry_walk() flags, similar to gmap_protect_rmap()?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261028185422.272146-1-imbrenda@linux.ibm.com?part=6

  reply	other threads:[~2026-10-28 19:10 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-28 18:54 [PATCH v4 0/7] KVM: s390: Misc bugfixes for 7.4 Claudio Imbrenda
2026-10-28 18:54 ` [PATCH v4 1/7] KVM: s390: Fix UCONTROL inconsistencies Claudio Imbrenda
2026-10-28 19:15   ` sashiko-bot
2026-10-28 18:54 ` [PATCH v4 2/7] KVM: s390: Move some skey functions to headers Claudio Imbrenda
2026-10-28 18:54 ` [PATCH v4 3/7] KVM: s390: Fix idte_crste() clobber and table type Claudio Imbrenda
2026-10-28 18:54 ` [PATCH v4 4/7] KVM: s390: Improve unmapping of large ranges Claudio Imbrenda
2026-10-28 19:10   ` sashiko-bot
2026-10-28 18:54 ` [PATCH v4 5/7] KVM: s390: vsie: Fix pinning using the wrong flag Claudio Imbrenda
2026-10-28 18:54 ` [PATCH v4 6/7] KVM: s390: Introduce gmap_allocate_all_page_tables_best_effort() Claudio Imbrenda
2026-10-28 19:10   ` sashiko-bot [this message]
2026-10-28 18:54 ` [PATCH v4 7/7] KVM: s390: Allocate page tables when CMMA is used Claudio Imbrenda
2026-10-28 19:28   ` sashiko-bot

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=sashiko-outbox-188342@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=agordeev@linux.ibm.com \
    --cc=borntraeger@linux.ibm.com \
    --cc=gor@linux.ibm.com \
    --cc=hca@linux.ibm.com \
    --cc=imbrenda@linux.ibm.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-s390@vger.kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /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