All of lore.kernel.org
 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: 15+ 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:57   ` sashiko-bot
2026-10-28 18:54 ` [PATCH v4 3/7] KVM: s390: Fix idte_crste() clobber and table type Claudio Imbrenda
2026-10-28 19:00   ` sashiko-bot
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:58   ` sashiko-bot
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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.