From: Claudio Imbrenda <imbrenda@linux.ibm.com>
To: kvm@vger.kernel.org
Cc: linux-s390@vger.kernel.org, borntraeger@de.ibm.com,
frankja@linux.ibm.com, david@kernel.org, nrb@linux.ibm.com,
schlameuss@linux.ibm.com, gra@linux.ibm.com
Subject: [PATCH v2 07/10] KVM: s390: Fix UCONTROL inconsistencies
Date: Fri, 23 Oct 2026 17:55:28 +0200 [thread overview]
Message-ID: <20261023155531.206113-8-imbrenda@linux.ibm.com> (raw)
In-Reply-To: <20261023155531.206113-1-imbrenda@linux.ibm.com>
For UCONTROL VMs, when a vCPU segment entry is mapped but unallocated,
the tl field was set to 1. This collides with the present bit, which
means that other parts of gmap would mistake the entry for a present
one.
Refactor the code to use a different combination of flags to indicate a
mapped but unallocated segment.
Fixes: a2c17f9270cc ("KVM: s390: New gmap code")
Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
---
arch/s390/kvm/gmap/dat.h | 16 +++++++++++-
arch/s390/kvm/gmap/gmap.c | 54 +++++++++++++++++++--------------------
2 files changed, 41 insertions(+), 29 deletions(-)
diff --git a/arch/s390/kvm/gmap/dat.h b/arch/s390/kvm/gmap/dat.h
index 319a8670fb10..3493f033e204 100644
--- a/arch/s390/kvm/gmap/dat.h
+++ b/arch/s390/kvm/gmap/dat.h
@@ -105,6 +105,8 @@ union pte {
#define _REGION3_FR_MASK (_REGION3_MASK >> PAGE_SHIFT)
#define _PAGES_PER_SEGMENT _PAGE_ENTRIES
#define _PAGES_PER_REGION3 (_PAGES_PER_SEGMENT * _CRST_ENTRIES)
+#define _UCAS_ENTRY_LENGTH 0
+#define _UCAS_ENTRY_OFFSET 3
#define CRDTE_NODAT IPTE_NODAT
#define CRDTE_GUEST_ASCE IPTE_GUEST_ASCE
@@ -429,6 +431,17 @@ static inline union crste _crste_fc0(kvm_pfn_t pfn, int tt)
return res;
}
+static inline union crste _crste_ucas(kvm_pfn_t pfn)
+{
+ union crste res = { .val = PFN_PHYS(pfn) };
+
+ res.h.i = 1;
+ res.h.tt = TABLE_TYPE_SEGMENT;
+ res.h.fc0.tl = _UCAS_ENTRY_LENGTH;
+ res.h.fc0.tf = _UCAS_ENTRY_OFFSET;
+ return res;
+}
+
/**
* _crste() - Useful constructor for union crste with FC=1
* @pfn: the pfn this pte should point to.
@@ -1027,7 +1040,8 @@ static inline int dat_create_slot(struct kvm_s390_mmu_cache *mc, struct dat_tabl
static inline bool crste_is_ucas(union crste crste)
{
- return is_pmd(crste) && crste.h.i && crste.h.fc0.tl == 1 && crste.h.fc == 0;
+ return is_pmd(crste) && crste.h.i && !crste.h.fc &&
+ crste.h.fc0.tl == _UCAS_ENTRY_LENGTH && crste.h.fc0.tf == _UCAS_ENTRY_OFFSET;
}
static inline void dat_set_storage_key_from_pgste(union pte pte, union pgste pgste)
diff --git a/arch/s390/kvm/gmap/gmap.c b/arch/s390/kvm/gmap/gmap.c
index c23da6fad92a..c10681f882c2 100644
--- a/arch/s390/kvm/gmap/gmap.c
+++ b/arch/s390/kvm/gmap/gmap.c
@@ -781,16 +781,14 @@ static int gmap_ucas_map_one(struct kvm_s390_mmu_cache *mc, struct gmap *gmap,
if (rc)
return rc;
if (!ptep) {
- newcrste = _crste_fc0(p_gfn, TABLE_TYPE_SEGMENT);
- newcrste.h.i = 1;
- newcrste.h.fc0.tl = 1;
+ newcrste = _crste_ucas(p_gfn);
} else {
pt = pte_table_start(ptep);
dat_set_ptval(pt, PTVAL_VMADDR, p_gfn >> (_SEGMENT_SHIFT - PAGE_SHIFT));
newcrste = _crste_fc0(virt_to_pfn(pt), TABLE_TYPE_SEGMENT);
}
- rc = dat_entry_walk(mc, c_gfn, gmap->datt, DAT_WALK_ALLOC, TABLE_TYPE_SEGMENT,
- &crstep, &ptep);
+ rc = dat_entry_walk(mc, c_gfn, gmap->datt, DAT_WALK_ALLOC | DAT_WALK_IGN_HOLES,
+ TABLE_TYPE_SEGMENT, &crstep, &ptep);
if (rc)
return rc;
do {
@@ -806,8 +804,9 @@ static int gmap_ucas_translate_simple(struct gmap *gmap, gpa_t *gaddr, union crs
union pte *ptep;
int rc;
- rc = dat_entry_walk(NULL, gpa_to_gfn(*gaddr), gmap->datt, DAT_WALK_CONTINUE,
- TABLE_TYPE_SEGMENT, crstepp, &ptep);
+ rc = dat_entry_walk(NULL, gpa_to_gfn(*gaddr), gmap->datt,
+ DAT_WALK_IGN_HOLES | DAT_WALK_ANY,
+ TABLE_TYPE_PAGE_TABLE, crstepp, &ptep);
if (rc || (!ptep && !crste_is_ucas(**crstepp)))
return -EREMOTE;
if (!ptep)
@@ -844,26 +843,24 @@ int gmap_ucas_translate(struct kvm_s390_mmu_cache *mc, struct gmap *gmap, gpa_t
if (rc <= 0)
return rc;
}
- do {
- scoped_guard(write_lock, &gmap->kvm->mmu_lock) {
- rc = gmap_ucas_translate_simple(gmap, gaddr, &crstep);
- if (rc <= 0)
- return rc;
- translated_address = (*gaddr & ~_SEGMENT_MASK) |
- (crstep->val & _SEGMENT_MASK);
- rc = gmap_ucas_map_one(mc, gmap, gpa_to_gfn(translated_address), gfn, true);
- }
- if (!rc) {
- *gaddr = translated_address;
- return 0;
- }
- if (rc != -ENOMEM)
- return -EREMOTE;
- rc = kvm_s390_mmu_cache_topup(mc);
- if (rc)
+ rc = kvm_s390_mmu_cache_topup(mc);
+ if (rc)
+ return rc;
+
+ scoped_guard(write_lock, &gmap->kvm->mmu_lock) {
+ rc = gmap_ucas_translate_simple(gmap, gaddr, &crstep);
+ if (rc <= 0)
return rc;
- } while (1);
- return 0;
+ translated_address = (*gaddr & ~_SEGMENT_MASK) |
+ (crstep->val & _SEGMENT_MASK);
+ rc = gmap_ucas_map_one(mc, gmap, gpa_to_gfn(translated_address), gfn, true);
+ }
+
+ if (!rc)
+ *gaddr = translated_address;
+ if (!rc || rc == -ENOMEM)
+ return rc;
+ return -EREMOTE;
}
int gmap_ucas_map(struct gmap *gmap, gfn_t p_gfn, gfn_t c_gfn, unsigned long count)
@@ -900,8 +897,9 @@ static void gmap_ucas_unmap_one(struct gmap *gmap, gfn_t c_gfn)
union pte *ptep;
int rc;
- rc = dat_entry_walk(NULL, c_gfn, gmap->datt, 0, TABLE_TYPE_SEGMENT, &crstep, &ptep);
- if (rc)
+ rc = dat_entry_walk(NULL, c_gfn, gmap->datt, DAT_WALK_IGN_HOLES,
+ TABLE_TYPE_SEGMENT, &crstep, &ptep);
+ if (rc || !is_pmd(*crstep))
return;
while (!dat_crstep_xchg_atomic(crstep, READ_ONCE(*crstep), _PMD_EMPTY,
c_gfn, gmap->datt.asce))
--
2.56.0
next prev parent reply other threads:[~2026-10-23 15:55 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-23 15:55 [PATCH v2 00/10] KVM: s390: Misc bugfixes and improvements for 7.4 Claudio Imbrenda
2026-10-23 15:55 ` [PATCH v2 01/10] KVM: s390: Move some skey functions to headers Claudio Imbrenda
2026-10-23 16:18 ` sashiko-bot
2026-10-26 8:32 ` Christoph Schlameuss
2026-10-23 15:55 ` [PATCH v2 02/10] KVM: s390: Refactor and improve DAT tables handling Claudio Imbrenda
2026-10-23 16:23 ` sashiko-bot
2026-10-23 15:55 ` [PATCH v2 03/10] KVM: s390: Move prefix marker from PGSTEs to PTEs Claudio Imbrenda
2026-10-23 16:40 ` sashiko-bot
2026-10-23 15:55 ` [PATCH v2 04/10] KVM: s390: Automatically enable storage keys for UCONTROL VMs Claudio Imbrenda
2026-10-23 16:32 ` sashiko-bot
2026-10-23 15:55 ` [PATCH v2 05/10] KVM: s390: Replace ASCE usage with a struct with more flags Claudio Imbrenda
2026-10-23 16:27 ` sashiko-bot
2026-10-23 15:55 ` [PATCH v2 06/10] KVM: s390: Rework some helper functions Claudio Imbrenda
2026-10-23 16:21 ` sashiko-bot
2026-10-26 10:03 ` Christoph Schlameuss
2026-10-23 15:55 ` Claudio Imbrenda [this message]
2026-10-23 16:47 ` [PATCH v2 07/10] KVM: s390: Fix UCONTROL inconsistencies sashiko-bot
2026-10-23 15:55 ` [PATCH v2 08/10] KVM: s390: Improve unmapping of large ranges Claudio Imbrenda
2026-10-23 17:17 ` sashiko-bot
2026-10-23 15:55 ` [PATCH v2 09/10] KVM: s390: vsie: Fix pinning using the wrong flag Claudio Imbrenda
2026-10-23 16:19 ` sashiko-bot
2026-10-23 15:55 ` [PATCH v2 10/10] KVM: s390: Enable 1M pages by default Claudio Imbrenda
2026-10-23 16:36 ` sashiko-bot
2026-10-26 10:31 ` 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=20261023155531.206113-8-imbrenda@linux.ibm.com \
--to=imbrenda@linux.ibm.com \
--cc=borntraeger@de.ibm.com \
--cc=david@kernel.org \
--cc=frankja@linux.ibm.com \
--cc=gra@linux.ibm.com \
--cc=kvm@vger.kernel.org \
--cc=linux-s390@vger.kernel.org \
--cc=nrb@linux.ibm.com \
--cc=schlameuss@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