* [PATCH v3 00/10] KVM: s390: Misc fixes
@ 2026-07-27 15:02 Claudio Imbrenda
2026-07-27 15:02 ` [PATCH v3 01/10] KVM: s390: Fix unlikely NULL gmap dereference Claudio Imbrenda
` (9 more replies)
0 siblings, 10 replies; 21+ messages in thread
From: Claudio Imbrenda @ 2026-07-27 15:02 UTC (permalink / raw)
To: linux-kernel
Cc: kvm, linux-s390, borntraeger, frankja, david, seiden, nrb,
schlameuss, gra
Fix a bunch of small issues that came up during the previous round of fixes.
They are mostly extremely unlikely races, but they should be fixed
nonetheless.
v2->v3
* Use READ_ONCE to pair with WRITE_ONCE in the first patch
* Fix leaking PGM_ADDRESSING also in kvm_s390_keyop() and related functions
* Fix and improve commit messages
* Use slots_arch_lock instead of slots_lock for ESSA operations
* Use normal spin_{,un}lock() functions instead of scoped_guard to avoid
mixing the two styles
* Use the newly introduced vcpu->arch.initialized to determine whether the
SCA entry needs to be cleared
* Improve handling of -EINTR; handle_mvpg_pei() needed some refactoring to
deal with it properly
* Three new patches:
- Free the mmu cache when kvm_arch_vcpu_create() fails
- Fix ordering when adding to SCA
- Fix cleanup in kvm_s390_pv_create_cpu()
v1->v2
* Drop some patches that have been picked upstream in the meantime.
* Drop patch 3, as it was trying to fix a bug that does not exist
* Avoid the NULL gmap dereference by using a flag
* Fix the return value of kvm_s390_[gp]et_skeys too
* Use kvm->slots_arch_lock instead of kvm->slots_lock for CMMA and ESSA
handling, to avoid potential deadlocks with the RCU.
* Three new patches to fix other issues that came out while fixing the
other issues
Claudio Imbrenda (10):
KVM: s390: Fix unlikely NULL gmap dereference
KVM: s390: Fix leaking of PGM_ADDRESSING to userspace
KVM: s390: Fix race in __do_essa()
KVM: s390: cmma: Fix dirty tracking when removing memslot
KVM: s390: ucontrol: Add missing locking around gmap_remove_child()
KVM: s390: Fix overclearing ESCA in case of error
KVM: s390: Return -EINTR if a signal was pending while faulting-in
KVM: s390: Free the mmu cache when kvm_arch_vcpu_create() fails
KVM: s390: Fix ordering when adding to SCA
KVM: s390: Fix cleanup in kvm_s390_pv_create_cpu()
arch/s390/include/asm/kvm_host.h | 1 +
arch/s390/kvm/dat.c | 23 ++++++----
arch/s390/kvm/dat.h | 2 +-
arch/s390/kvm/faultin.c | 4 +-
arch/s390/kvm/intercept.c | 18 ++++----
arch/s390/kvm/interrupt.c | 2 +-
arch/s390/kvm/kvm-s390.c | 72 ++++++++++++++++++++++----------
arch/s390/kvm/priv.c | 10 +++--
arch/s390/kvm/pv.c | 43 +++++++++----------
9 files changed, 106 insertions(+), 69 deletions(-)
--
2.55.0
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH v3 01/10] KVM: s390: Fix unlikely NULL gmap dereference
2026-07-27 15:02 [PATCH v3 00/10] KVM: s390: Misc fixes Claudio Imbrenda
@ 2026-07-27 15:02 ` Claudio Imbrenda
2026-07-27 15:24 ` sashiko-bot
2026-07-27 15:02 ` [PATCH v3 02/10] KVM: s390: Fix leaking of PGM_ADDRESSING to userspace Claudio Imbrenda
` (8 subsequent siblings)
9 siblings, 1 reply; 21+ messages in thread
From: Claudio Imbrenda @ 2026-07-27 15:02 UTC (permalink / raw)
To: linux-kernel
Cc: kvm, linux-s390, borntraeger, frankja, david, seiden, nrb,
schlameuss, gra
When creating a new vCPU, kvm_vm_ioctl_create_vcpu() will call
kvm_arch_vcpu_postcreate() after the file descriptor for the new vCPU
has been created. The new file descriptor has not been returned yet,
but a malicious userspace program could try to guess it.
If a malicious userspace program manages to start the newly created vCPU
before kvm_arch_vcpu_postcreate() is called, __vcpu_run() will try to
dereference vcpu->arch.gmap and trigger a NULL pointer dereference.
Fix this by adding a new field to struct kvm_vcpu_arch to keep track of
the initialization status of the vCPU. Refuse to run a vCPU that is not
fully initialized.
Fixes: dafd032a15f8 ("KVM: s390: move vcpu specific initalization to a later point")
Fixes: e38c884df921 ("KVM: s390: Switch to new gmap")
Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
---
arch/s390/include/asm/kvm_host.h | 1 +
arch/s390/kvm/kvm-s390.c | 8 ++++++++
2 files changed, 9 insertions(+)
diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h
index eaa34c5bd3c1..edf75b6ad20c 100644
--- a/arch/s390/include/asm/kvm_host.h
+++ b/arch/s390/include/asm/kvm_host.h
@@ -440,6 +440,7 @@ struct kvm_vcpu_arch {
bool skey_enabled;
/* Indicator if the access registers have been loaded from guest */
bool acrs_loaded;
+ bool initialized;
struct kvm_s390_pv_vcpu pv;
union diag318_info diag318_info;
struct kvm_s390_mmu_cache *mc;
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 150b5dd2170e..22535f76ae05 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -3613,6 +3613,8 @@ void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu)
if (test_kvm_facility(vcpu->kvm, 74) || vcpu->kvm->arch.user_instr0 ||
vcpu->kvm->arch.user_operexec)
vcpu->arch.sie_block->ictl |= ICTL_OPEREXC;
+
+ WRITE_ONCE(vcpu->arch.initialized, true);
}
static bool kvm_has_pckmo_subfunc(struct kvm *kvm, unsigned long nr)
@@ -5039,6 +5041,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
kvm_run->kvm_dirty_regs & ~KVM_SYNC_S390_VALID_FIELDS)
return -EINVAL;
+ if (!READ_ONCE(vcpu->arch.initialized))
+ return -EINVAL;
+
vcpu_load(vcpu);
if (guestdbg_exit_pending(vcpu)) {
@@ -5523,6 +5528,9 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
long r;
u16 rc, rrc;
+ if (!READ_ONCE(vcpu->arch.initialized))
+ return -EINVAL;
+
vcpu_load(vcpu);
switch (ioctl) {
--
2.55.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v3 02/10] KVM: s390: Fix leaking of PGM_ADDRESSING to userspace
2026-07-27 15:02 [PATCH v3 00/10] KVM: s390: Misc fixes Claudio Imbrenda
2026-07-27 15:02 ` [PATCH v3 01/10] KVM: s390: Fix unlikely NULL gmap dereference Claudio Imbrenda
@ 2026-07-27 15:02 ` Claudio Imbrenda
2026-07-27 15:33 ` sashiko-bot
2026-07-27 15:02 ` [PATCH v3 03/10] KVM: s390: Fix race in __do_essa() Claudio Imbrenda
` (7 subsequent siblings)
9 siblings, 1 reply; 21+ messages in thread
From: Claudio Imbrenda @ 2026-07-27 15:02 UTC (permalink / raw)
To: linux-kernel
Cc: kvm, linux-s390, borntraeger, frankja, david, seiden, nrb,
schlameuss, gra
If kvm_s390_set_cmma_bits() is asked to set CMMA values outside of a
memslot, PGM_ADDRESSING (5) is returned, instead of a negative error
value.
Same issue with kvm_s390_{g,s}et_skeys(), kvm_s390_keyop(), and
dat_reset_reference_bit().
Fix by returning -EFAULT whenever the return value would be > 0, which
is consistent with the behaviour before the gmap rewrite.
Fixes: e38c884df921 ("KVM: s390: Switch to new gmap")
Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
---
arch/s390/kvm/dat.c | 16 ++++++++++------
arch/s390/kvm/dat.h | 2 +-
arch/s390/kvm/kvm-s390.c | 16 ++++++++--------
arch/s390/kvm/priv.c | 5 +++--
4 files changed, 22 insertions(+), 17 deletions(-)
diff --git a/arch/s390/kvm/dat.c b/arch/s390/kvm/dat.c
index ed4259d17629..171b61959908 100644
--- a/arch/s390/kvm/dat.c
+++ b/arch/s390/kvm/dat.c
@@ -755,13 +755,15 @@ int dat_cond_set_storage_key(struct kvm_s390_mmu_cache *mmc, union asce asce, gf
return rc;
}
-int dat_reset_reference_bit(union asce asce, gfn_t gfn)
+int dat_reset_reference_bit(union asce asce, gfn_t gfn, union skey *skey)
{
union pgste pgste, old;
union crste *crstep;
union pte *ptep;
int rc;
+ skey->skey = 0;
+
rc = dat_entry_walk(NULL, gfn, asce, DAT_WALK_ANY, TABLE_TYPE_PAGE_TABLE, &crstep, &ptep);
if (rc)
return rc;
@@ -771,21 +773,23 @@ int dat_reset_reference_bit(union asce asce, gfn_t gfn)
if (!crste.h.fc || !crste.s.fc1.pr)
return 0;
- return page_reset_referenced(large_crste_to_phys(*crstep, gfn));
+ skey->skey = page_reset_referenced(large_crste_to_phys(*crstep, gfn)) << 1;
+ return 0;
}
old = pgste_get_lock(ptep);
pgste = old;
if (!ptep->h.i) {
- rc = page_reset_referenced(pte_origin(*ptep));
- pgste.hr = rc >> 1;
+ skey->skey = page_reset_referenced(pte_origin(*ptep)) << 1;
+ pgste.hr = skey->r;
}
- rc |= (pgste.gr << 1) | pgste.gc;
+ skey->r |= pgste.gr;
+ skey->c |= pgste.gc;
pgste.gr = 0;
dat_update_ptep_sd(old, pgste, ptep);
pgste_set_unlock(ptep, pgste);
- return rc;
+ return 0;
}
static long dat_reset_skeys_pte(union pte *ptep, gfn_t gfn, gfn_t next, struct dat_walk *walk)
diff --git a/arch/s390/kvm/dat.h b/arch/s390/kvm/dat.h
index fad605305e05..141ee7b9f019 100644
--- a/arch/s390/kvm/dat.h
+++ b/arch/s390/kvm/dat.h
@@ -537,7 +537,7 @@ int dat_set_storage_key(struct kvm_s390_mmu_cache *mc, union asce asce, gfn_t gf
union skey skey, bool nq);
int dat_cond_set_storage_key(struct kvm_s390_mmu_cache *mmc, union asce asce, gfn_t gfn,
union skey skey, union skey *oldkey, bool nq, bool mr, bool mc);
-int dat_reset_reference_bit(union asce asce, gfn_t gfn);
+int dat_reset_reference_bit(union asce asce, gfn_t gfn, union skey *skey);
long dat_reset_skeys(union asce asce, gfn_t start);
unsigned long dat_get_ptval(struct page_table *table, struct ptval_param param);
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 22535f76ae05..efd4042d195b 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -571,7 +571,7 @@ static int kvm_s390_keyop(struct kvm_s390_mmu_cache *mc, struct kvm *kvm, int op
switch (op) {
case KVM_S390_KEYOP_SSKE:
r = dat_cond_set_storage_key(mc, asce, gfn, skey, &skey, 0, 0, 0);
- if (r >= 0)
+ if (r == 0 || r == 1)
return skey.skey;
break;
case KVM_S390_KEYOP_ISKE:
@@ -580,14 +580,14 @@ static int kvm_s390_keyop(struct kvm_s390_mmu_cache *mc, struct kvm *kvm, int op
return skey.skey;
break;
case KVM_S390_KEYOP_RRBE:
- r = dat_reset_reference_bit(asce, gfn);
- if (r > 0)
- return r << 1;
+ r = dat_reset_reference_bit(asce, gfn, &skey);
+ if (!r)
+ return skey.skey;
break;
default:
return -EINVAL;
}
- return r;
+ return r > 0 ? -EFAULT : r;
}
/* Section: device related */
@@ -2214,7 +2214,7 @@ static int kvm_s390_get_skeys(struct kvm *kvm, struct kvm_s390_skeys *args)
}
kvfree(keys);
- return r;
+ return r <= 0 ? r : -EFAULT;
}
static int kvm_s390_set_skeys(struct kvm *kvm, struct kvm_s390_skeys *args)
@@ -2276,7 +2276,7 @@ static int kvm_s390_set_skeys(struct kvm *kvm, struct kvm_s390_skeys *args)
kvm_s390_free_mmu_cache(mc);
out:
kvfree(keys);
- return r;
+ return r <= 0 ? r : -EFAULT;
}
/*
@@ -2386,7 +2386,7 @@ static int kvm_s390_set_cmma_bits(struct kvm *kvm,
set_bit(GMAP_FLAG_USES_CMM, &kvm->arch.gmap->flags);
- return r;
+ return r <= 0 ? r : -EFAULT;
}
/**
diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c
index ad0ddc433a73..ea5a99537346 100644
--- a/arch/s390/kvm/priv.c
+++ b/arch/s390/kvm/priv.c
@@ -289,6 +289,7 @@ static int handle_iske(struct kvm_vcpu *vcpu)
static int handle_rrbe(struct kvm_vcpu *vcpu)
{
unsigned long gaddr;
+ union skey skey;
int reg1, reg2;
int rc;
@@ -307,12 +308,12 @@ static int handle_rrbe(struct kvm_vcpu *vcpu)
gaddr = kvm_s390_logical_to_effective(vcpu, gaddr);
gaddr = kvm_s390_real_to_abs(vcpu, gaddr);
scoped_guard(read_lock, &vcpu->kvm->mmu_lock)
- rc = dat_reset_reference_bit(vcpu->arch.gmap->asce, gpa_to_gfn(gaddr));
+ rc = dat_reset_reference_bit(vcpu->arch.gmap->asce, gpa_to_gfn(gaddr), &skey);
if (rc > 0)
return kvm_s390_inject_program_int(vcpu, rc);
if (rc < 0)
return rc;
- kvm_s390_set_psw_cc(vcpu, rc);
+ kvm_s390_set_psw_cc(vcpu, (skey.skey >> 1) & 3);
return 0;
}
--
2.55.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v3 03/10] KVM: s390: Fix race in __do_essa()
2026-07-27 15:02 [PATCH v3 00/10] KVM: s390: Misc fixes Claudio Imbrenda
2026-07-27 15:02 ` [PATCH v3 01/10] KVM: s390: Fix unlikely NULL gmap dereference Claudio Imbrenda
2026-07-27 15:02 ` [PATCH v3 02/10] KVM: s390: Fix leaking of PGM_ADDRESSING to userspace Claudio Imbrenda
@ 2026-07-27 15:02 ` Claudio Imbrenda
2026-07-27 15:43 ` sashiko-bot
2026-07-27 15:02 ` [PATCH v3 04/10] KVM: s390: cmma: Fix dirty tracking when removing memslot Claudio Imbrenda
` (6 subsequent siblings)
9 siblings, 1 reply; 21+ messages in thread
From: Claudio Imbrenda @ 2026-07-27 15:02 UTC (permalink / raw)
To: linux-kernel
Cc: kvm, linux-s390, borntraeger, frankja, david, seiden, nrb,
schlameuss, gra
An unlikely race between __do_essa() and kvm_s390_vm_start_migration(),
kvm_s390_vm_stop_migration(), or dat_get_cmma() was possible.
Fix by locking kvm->slots_lock. Since this is not a hot path, the
overhead of an additional mutex is negligible.
Fixes: e38c884df921 ("KVM: s390: Switch to new gmap")
Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
---
arch/s390/kvm/kvm-s390.c | 14 +++++++-------
arch/s390/kvm/priv.c | 5 +++--
2 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index efd4042d195b..879fdc42cb71 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -1300,7 +1300,9 @@ static int kvm_s390_vm_set_migration(struct kvm *kvm,
{
int res = -ENXIO;
- mutex_lock(&kvm->slots_lock);
+ guard(srcu)(&kvm->srcu);
+ guard(mutex)(&kvm->slots_arch_lock);
+
switch (attr->attr) {
case KVM_S390_VM_MIGRATION_START:
res = kvm_s390_vm_start_migration(kvm);
@@ -1311,7 +1313,6 @@ static int kvm_s390_vm_set_migration(struct kvm *kvm,
default:
break;
}
- mutex_unlock(&kvm->slots_lock);
return res;
}
@@ -2998,9 +2999,8 @@ int kvm_arch_vm_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg)
r = -EFAULT;
if (copy_from_user(&args, argp, sizeof(args)))
break;
- mutex_lock(&kvm->slots_lock);
- r = kvm_s390_get_cmma_bits(kvm, &args);
- mutex_unlock(&kvm->slots_lock);
+ scoped_guard(mutex, &kvm->slots_arch_lock)
+ r = kvm_s390_get_cmma_bits(kvm, &args);
if (!r) {
r = copy_to_user(argp, &args, sizeof(args));
if (r)
@@ -3014,9 +3014,9 @@ int kvm_arch_vm_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg)
r = -EFAULT;
if (copy_from_user(&args, argp, sizeof(args)))
break;
- mutex_lock(&kvm->slots_lock);
+ mutex_lock(&kvm->slots_arch_lock);
r = kvm_s390_set_cmma_bits(kvm, &args);
- mutex_unlock(&kvm->slots_lock);
+ mutex_unlock(&kvm->slots_arch_lock);
break;
}
case KVM_S390_PV_COMMAND: {
diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c
index ea5a99537346..b1ba24c346ef 100644
--- a/arch/s390/kvm/priv.c
+++ b/arch/s390/kvm/priv.c
@@ -1261,8 +1261,9 @@ static int handle_essa(struct kvm_vcpu *vcpu)
/* Retry the ESSA instruction */
kvm_s390_retry_instr(vcpu);
} else {
- scoped_guard(read_lock, &vcpu->kvm->mmu_lock)
- i = __do_essa(vcpu, orc);
+ scoped_guard(mutex, &vcpu->kvm->slots_arch_lock)
+ scoped_guard(read_lock, &vcpu->kvm->mmu_lock)
+ i = __do_essa(vcpu, orc);
if (i < 0)
return i;
/* Account for the possible extra cbrl entry */
--
2.55.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v3 04/10] KVM: s390: cmma: Fix dirty tracking when removing memslot
2026-07-27 15:02 [PATCH v3 00/10] KVM: s390: Misc fixes Claudio Imbrenda
` (2 preceding siblings ...)
2026-07-27 15:02 ` [PATCH v3 03/10] KVM: s390: Fix race in __do_essa() Claudio Imbrenda
@ 2026-07-27 15:02 ` Claudio Imbrenda
2026-07-27 16:03 ` sashiko-bot
2026-07-27 15:02 ` [PATCH v3 05/10] KVM: s390: ucontrol: Add missing locking around gmap_remove_child() Claudio Imbrenda
` (5 subsequent siblings)
9 siblings, 1 reply; 21+ messages in thread
From: Claudio Imbrenda @ 2026-07-27 15:02 UTC (permalink / raw)
To: linux-kernel
Cc: kvm, linux-s390, borntraeger, frankja, david, seiden, nrb,
schlameuss, gra
When a memslot is removed, all ptes that mapped the slot are cleared or
even deallocated. If this happens while the system is in migration
mode, and if cmma-dirty pages are removed, the cmma-dirty counter will
not reflect reality.
Fix by appropriately decrementing the cmma-dirty counter when removing
a memslot.
Fixes: e38c884df921 ("KVM: s390: Switch to new gmap")
Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
---
arch/s390/kvm/dat.c | 7 ++++++-
arch/s390/kvm/kvm-s390.c | 16 ++++++++++++++++
2 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/arch/s390/kvm/dat.c b/arch/s390/kvm/dat.c
index 171b61959908..3f2d6e8902d7 100644
--- a/arch/s390/kvm/dat.c
+++ b/arch/s390/kvm/dat.c
@@ -850,6 +850,7 @@ static long _dat_slot_pte(union pte *ptep, gfn_t gfn, gfn_t next, struct dat_wal
struct slot_priv *p = walk->priv;
union crste dummy = { .val = p->token };
union pte new_pte, pte = READ_ONCE(*ptep);
+ union pgste pgste;
new_pte = _PTE_TOK(dummy.tok.type, dummy.tok.par);
@@ -857,7 +858,11 @@ static long _dat_slot_pte(union pte *ptep, gfn_t gfn, gfn_t next, struct dat_wal
if (pte.val == new_pte.val)
return 0;
- dat_ptep_xchg(ptep, new_pte, gfn, walk->asce, false);
+ pgste = pgste_get_lock(ptep);
+ pgste = __dat_ptep_xchg(ptep, pgste, new_pte, gfn, walk->asce, false);
+ pgste.cmma_d = 0;
+ pgste_set_unlock(ptep, pgste);
+
return 0;
}
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 879fdc42cb71..19294d8dff96 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -5802,11 +5802,19 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
return 0;
}
+static long cmma_d_count_pte(union pte *ptep, gfn_t gfn, gfn_t next, struct dat_walk *walk)
+{
+ if (pgste_of(ptep)->cmma_d)
+ atomic64_dec(walk->priv);
+ return 0;
+}
+
void kvm_arch_commit_memory_region(struct kvm *kvm,
struct kvm_memory_slot *old,
const struct kvm_memory_slot *new,
enum kvm_mr_change change)
{
+ const struct dat_walk_ops ops = { .pte_entry = cmma_d_count_pte, };
struct kvm_s390_mmu_cache *mc = NULL;
int rc = 0;
@@ -5819,7 +5827,15 @@ void kvm_arch_commit_memory_region(struct kvm *kvm,
goto out;
}
+ guard(mutex)(&kvm->slots_arch_lock);
+
scoped_guard(write_lock, &kvm->mmu_lock) {
+ if (kvm->arch.migration_mode && kvm->arch.use_cmma) {
+ _dat_walk_gfn_range(old->base_gfn, old->base_gfn + old->npages,
+ kvm->arch.gmap->asce, &ops, DAT_WALK_IGN_HOLES,
+ &kvm->arch.cmma_dirty_pages);
+ }
+
switch (change) {
case KVM_MR_DELETE:
rc = dat_delete_slot(mc, kvm->arch.gmap->asce, old->base_gfn, old->npages);
--
2.55.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v3 05/10] KVM: s390: ucontrol: Add missing locking around gmap_remove_child()
2026-07-27 15:02 [PATCH v3 00/10] KVM: s390: Misc fixes Claudio Imbrenda
` (3 preceding siblings ...)
2026-07-27 15:02 ` [PATCH v3 04/10] KVM: s390: cmma: Fix dirty tracking when removing memslot Claudio Imbrenda
@ 2026-07-27 15:02 ` Claudio Imbrenda
2026-07-27 16:14 ` sashiko-bot
2026-07-27 15:02 ` [PATCH v3 06/10] KVM: s390: Fix overclearing ESCA in case of error Claudio Imbrenda
` (4 subsequent siblings)
9 siblings, 1 reply; 21+ messages in thread
From: Claudio Imbrenda @ 2026-07-27 15:02 UTC (permalink / raw)
To: linux-kernel
Cc: kvm, linux-s390, borntraeger, frankja, david, seiden, nrb,
schlameuss, gra
gmap_remove_child() needs to be called while holding the children_lock
of the parent gmap. This was not the case in the error handling path of
kvm_arch_vcpu_create() for UCONTROL guests.
Fix by adding the missing lock.
Fixes: e38c884df921 ("KVM: s390: Switch to new gmap")
Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
---
arch/s390/kvm/kvm-s390.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 19294d8dff96..9fccba261930 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -3869,7 +3869,9 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
out_ucontrol_uninit:
if (kvm_is_ucontrol(vcpu->kvm)) {
+ spin_lock(&vcpu->kvm->arch.gmap->children_lock);
gmap_remove_child(vcpu->arch.gmap);
+ spin_unlock(&vcpu->kvm->arch.gmap->children_lock);
vcpu->arch.gmap = gmap_put(vcpu->arch.gmap);
}
out_free_sie_block:
--
2.55.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v3 06/10] KVM: s390: Fix overclearing ESCA in case of error
2026-07-27 15:02 [PATCH v3 00/10] KVM: s390: Misc fixes Claudio Imbrenda
` (4 preceding siblings ...)
2026-07-27 15:02 ` [PATCH v3 05/10] KVM: s390: ucontrol: Add missing locking around gmap_remove_child() Claudio Imbrenda
@ 2026-07-27 15:02 ` Claudio Imbrenda
2026-07-27 16:33 ` sashiko-bot
2026-07-27 15:02 ` [PATCH v3 07/10] KVM: s390: Return -EINTR if a signal was pending while faulting-in Claudio Imbrenda
` (3 subsequent siblings)
9 siblings, 1 reply; 21+ messages in thread
From: Claudio Imbrenda @ 2026-07-27 15:02 UTC (permalink / raw)
To: linux-kernel
Cc: kvm, linux-s390, borntraeger, frankja, david, seiden, nrb,
schlameuss, gra
If an attempt is made to create a vCPU with an already existing ID,
the duplicated vCPU will be destroyed. When destroying a vCPU, its
ESCA entry will be cleared. In the above scenario, the spurious
duplicate vCPU is destroyed, but the ESCA entry corresponding to the
original vCPU is cleared.
Fix by skipping clearing the ESCA entry if the vCPU creation was not
successful, i.e. if the pointer to the ESCA in the state description is
not set.
Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
Reviewed-by: Janosch Frank <frankja@linux.ibm.com>
---
arch/s390/kvm/interrupt.c | 2 +-
arch/s390/kvm/kvm-s390.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
index 9e3e6b0d72ad..2acdff130fa6 100644
--- a/arch/s390/kvm/interrupt.c
+++ b/arch/s390/kvm/interrupt.c
@@ -86,7 +86,7 @@ static void sca_clear_ext_call(struct kvm_vcpu *vcpu)
struct esca_block *sca = vcpu->kvm->arch.sca;
union esca_sigp_ctrl *sigp_ctrl = &sca->cpu[vcpu->vcpu_id].sigp_ctrl;
- if (!kvm_s390_use_sca_entries())
+ if (!kvm_s390_use_sca_entries() || !vcpu->arch.initialized)
return;
kvm_s390_clear_cpuflags(vcpu, CPUSTAT_ECALL_PEND);
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 9fccba261930..69c9027c42bf 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -3461,7 +3461,7 @@ static void sca_del_vcpu(struct kvm_vcpu *vcpu)
{
struct esca_block *sca = vcpu->kvm->arch.sca;
- if (!kvm_s390_use_sca_entries())
+ if (!kvm_s390_use_sca_entries() || !vcpu->arch.initialized)
return;
clear_bit_inv(vcpu->vcpu_id, (unsigned long *)sca->mcn);
--
2.55.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v3 07/10] KVM: s390: Return -EINTR if a signal was pending while faulting-in
2026-07-27 15:02 [PATCH v3 00/10] KVM: s390: Misc fixes Claudio Imbrenda
` (5 preceding siblings ...)
2026-07-27 15:02 ` [PATCH v3 06/10] KVM: s390: Fix overclearing ESCA in case of error Claudio Imbrenda
@ 2026-07-27 15:02 ` Claudio Imbrenda
2026-07-27 16:59 ` sashiko-bot
2026-07-27 15:02 ` [PATCH v3 08/10] KVM: s390: Free the mmu cache when kvm_arch_vcpu_create() fails Claudio Imbrenda
` (2 subsequent siblings)
9 siblings, 1 reply; 21+ messages in thread
From: Claudio Imbrenda @ 2026-07-27 15:02 UTC (permalink / raw)
To: linux-kernel
Cc: kvm, linux-s390, borntraeger, frankja, david, seiden, nrb,
schlameuss, gra
If a signal is pending while trying to fault-in a page, return -EINTR
instead of -EAGAIN.
Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
Fixes: e907ae530133 ("KVM: s390: Add helper functions for fault handling")
---
arch/s390/kvm/faultin.c | 4 ++--
arch/s390/kvm/intercept.c | 18 ++++++++----------
arch/s390/kvm/pv.c | 2 +-
3 files changed, 11 insertions(+), 13 deletions(-)
diff --git a/arch/s390/kvm/faultin.c b/arch/s390/kvm/faultin.c
index fee80047bd94..4ff4c5970956 100644
--- a/arch/s390/kvm/faultin.c
+++ b/arch/s390/kvm/faultin.c
@@ -92,8 +92,8 @@ int kvm_s390_faultin_gfn(struct kvm_vcpu *vcpu, struct kvm *kvm, struct guest_fa
if (is_noslot_pfn(f->pfn))
return PGM_ADDRESSING;
/* Signal pending: try again. */
- if (f->pfn == KVM_PFN_ERR_SIGPENDING)
- return -EAGAIN;
+ if (is_sigpending_pfn(f->pfn))
+ return -EINTR;
/* Check if it's read-only memory; don't try to actually handle that case. */
if (f->pfn == KVM_PFN_ERR_RO_FAULT)
return -EOPNOTSUPP;
diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c
index 1980df61ef30..08f2128db147 100644
--- a/arch/s390/kvm/intercept.c
+++ b/arch/s390/kvm/intercept.c
@@ -369,27 +369,25 @@ static int handle_mvpg_pei(struct kvm_vcpu *vcpu)
if (rc)
return kvm_s390_inject_prog_cond(vcpu, rc);
- do {
- rc = kvm_s390_faultin_gfn_simple(vcpu, NULL, gpa_to_gfn(srcaddr), false);
- } while (rc == -EAGAIN);
- if (rc)
- return rc;
-
- /* Ensure that the source is paged-in, no actual access -> no key checking */
+ /* Ensure that the destination is paged-in, no actual access -> no key checking */
rc = guest_translate_address_with_key(vcpu, vcpu->run->s.regs.gprs[reg1],
reg1, &dstaddr, GACC_STORE, 0);
if (rc)
return kvm_s390_inject_prog_cond(vcpu, rc);
+ kvm_s390_retry_instr(vcpu);
+
do {
- rc = kvm_s390_faultin_gfn_simple(vcpu, NULL, gpa_to_gfn(dstaddr), true);
+ rc = kvm_s390_faultin_gfn_simple(vcpu, NULL, gpa_to_gfn(srcaddr), false);
} while (rc == -EAGAIN);
if (rc)
return rc;
- kvm_s390_retry_instr(vcpu);
+ do {
+ rc = kvm_s390_faultin_gfn_simple(vcpu, NULL, gpa_to_gfn(dstaddr), true);
+ } while (rc == -EAGAIN);
- return 0;
+ return rc;
}
static int handle_partial_execution(struct kvm_vcpu *vcpu)
diff --git a/arch/s390/kvm/pv.c b/arch/s390/kvm/pv.c
index 1beacc841ca8..dc204b521052 100644
--- a/arch/s390/kvm/pv.c
+++ b/arch/s390/kvm/pv.c
@@ -809,7 +809,7 @@ static int unpack_one(struct kvm *kvm, unsigned long addr, u64 tweak,
return -EAGAIN;
}
- if (ret && ret != -EAGAIN)
+ if (ret && ret != -EAGAIN && ret != -EINTR)
KVM_UV_EVENT(kvm, 3, "PROTVIRT VM UNPACK: failed addr %llx with rc %x rrc %x",
uvcb.gaddr, *rc, *rrc);
return ret;
--
2.55.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v3 08/10] KVM: s390: Free the mmu cache when kvm_arch_vcpu_create() fails
2026-07-27 15:02 [PATCH v3 00/10] KVM: s390: Misc fixes Claudio Imbrenda
` (6 preceding siblings ...)
2026-07-27 15:02 ` [PATCH v3 07/10] KVM: s390: Return -EINTR if a signal was pending while faulting-in Claudio Imbrenda
@ 2026-07-27 15:02 ` Claudio Imbrenda
2026-07-27 17:06 ` sashiko-bot
2026-07-27 15:02 ` [PATCH v3 09/10] KVM: s390: Fix ordering when adding to SCA Claudio Imbrenda
2026-07-27 15:02 ` [PATCH v3 10/10] KVM: s390: Fix cleanup in kvm_s390_pv_create_cpu() Claudio Imbrenda
9 siblings, 1 reply; 21+ messages in thread
From: Claudio Imbrenda @ 2026-07-27 15:02 UTC (permalink / raw)
To: linux-kernel
Cc: kvm, linux-s390, borntraeger, frankja, david, seiden, nrb,
schlameuss, gra
The mmu cache is the first thing that is allocated in
kvm_arch_vcpu_create(), but in case of failure it was not freed.
Fix by freeing the mmu cache in case of failure.
Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
Fixes: e38c884df921 ("KVM: s390: Switch to new gmap")
---
arch/s390/kvm/kvm-s390.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 69c9027c42bf..8afb88a2b73d 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -3796,19 +3796,17 @@ int kvm_arch_vcpu_precreate(struct kvm *kvm, unsigned int id)
int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
{
+ struct kvm_s390_mmu_cache *mc __free(kvm_s390_mmu_cache) = NULL;
struct sie_page *sie_page;
int rc;
BUILD_BUG_ON(sizeof(struct sie_page) != 4096);
- vcpu->arch.mc = kvm_s390_new_mmu_cache();
- if (!vcpu->arch.mc)
+ mc = kvm_s390_new_mmu_cache();
+ if (!mc)
return -ENOMEM;
sie_page = (struct sie_page *) get_zeroed_page(GFP_KERNEL_ACCOUNT);
- if (!sie_page) {
- kvm_s390_free_mmu_cache(vcpu->arch.mc);
- vcpu->arch.mc = NULL;
+ if (!sie_page)
return -ENOMEM;
- }
vcpu->arch.sie_block = &sie_page->sie_block;
vcpu->arch.sie_block->itdba = virt_to_phys(&sie_page->itdb);
@@ -3864,6 +3862,8 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
if (rc)
goto out_ucontrol_uninit;
+ vcpu->arch.mc = mc;
+ mc = NULL;
kvm_s390_update_topology_change_report(vcpu->kvm, 1);
return 0;
--
2.55.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v3 09/10] KVM: s390: Fix ordering when adding to SCA
2026-07-27 15:02 [PATCH v3 00/10] KVM: s390: Misc fixes Claudio Imbrenda
` (7 preceding siblings ...)
2026-07-27 15:02 ` [PATCH v3 08/10] KVM: s390: Free the mmu cache when kvm_arch_vcpu_create() fails Claudio Imbrenda
@ 2026-07-27 15:02 ` Claudio Imbrenda
2026-07-27 17:12 ` sashiko-bot
2026-07-27 15:02 ` [PATCH v3 10/10] KVM: s390: Fix cleanup in kvm_s390_pv_create_cpu() Claudio Imbrenda
9 siblings, 1 reply; 21+ messages in thread
From: Claudio Imbrenda @ 2026-07-27 15:02 UTC (permalink / raw)
To: linux-kernel
Cc: kvm, linux-s390, borntraeger, frankja, david, seiden, nrb,
schlameuss, gra
When adding a new vCPU to the SCA area, the validity bit in the MCN was
set before the pointer to the state description, potentially allowing
for a race.
Fix by setting the pointer before setting the bit.
Fixes: 14542a0a54c5 ("KVM: S390: Remove sca_lock")
Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
---
arch/s390/kvm/kvm-s390.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 8afb88a2b73d..85dcd40b2fa1 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -3481,8 +3481,8 @@ static void sca_add_vcpu(struct kvm_vcpu *vcpu)
if (!kvm_s390_use_sca_entries())
return;
+ WRITE_ONCE(sca->cpu[vcpu->vcpu_id].sda, virt_to_phys(vcpu->arch.sie_block));
set_bit_inv(vcpu->vcpu_id, (unsigned long *)sca->mcn);
- sca->cpu[vcpu->vcpu_id].sda = virt_to_phys(vcpu->arch.sie_block);
}
static int sca_can_add_vcpu(struct kvm *kvm, unsigned int id)
--
2.55.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v3 10/10] KVM: s390: Fix cleanup in kvm_s390_pv_create_cpu()
2026-07-27 15:02 [PATCH v3 00/10] KVM: s390: Misc fixes Claudio Imbrenda
` (8 preceding siblings ...)
2026-07-27 15:02 ` [PATCH v3 09/10] KVM: s390: Fix ordering when adding to SCA Claudio Imbrenda
@ 2026-07-27 15:02 ` Claudio Imbrenda
2026-07-27 17:18 ` sashiko-bot
9 siblings, 1 reply; 21+ messages in thread
From: Claudio Imbrenda @ 2026-07-27 15:02 UTC (permalink / raw)
To: linux-kernel
Cc: kvm, linux-s390, borntraeger, frankja, david, seiden, nrb,
schlameuss, gra
If creating a protected vCPU in kvm_s390_pv_create_cpu() fails,
kvm_s390_pv_destroy_cpu() was called, which checks whether the vCPU has
a PV handle and exits doing nothing otherwise. At that point, due to
not having created the protected vCPU, the PV handle will not be set,
and kvm_s390_pv_destroy_cpu() will do nothing, thus leaking the
allocated memory.
Fix by factoring out the code to free and reset a PV vCPU; call it from
kvm_s390_pv_destroy_cpu() and kvm_s390_pv_create_cpu().
Fixes: d4074324b07a ("KVM: s390: pv: avoid double free of sida page")
Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
---
arch/s390/kvm/pv.c | 41 +++++++++++++++++++++--------------------
1 file changed, 21 insertions(+), 20 deletions(-)
diff --git a/arch/s390/kvm/pv.c b/arch/s390/kvm/pv.c
index dc204b521052..b02e0159d3cd 100644
--- a/arch/s390/kvm/pv.c
+++ b/arch/s390/kvm/pv.c
@@ -244,6 +244,24 @@ static void kvm_s390_clear_pv_state(struct kvm *kvm)
kvm->arch.pv.stor_var = NULL;
}
+static void kvm_s390_pv_dispose_cpu(struct kvm_vcpu *vcpu, bool free_stor_base)
+{
+ if (free_stor_base)
+ free_pages(vcpu->arch.pv.stor_base, get_order(uv_info.guest_cpu_stor_len));
+ free_page((unsigned long)sida_addr(vcpu->arch.sie_block));
+ vcpu->arch.sie_block->pv_handle_cpu = 0;
+ vcpu->arch.sie_block->pv_handle_config = 0;
+ memset(&vcpu->arch.pv, 0, sizeof(vcpu->arch.pv));
+ vcpu->arch.sie_block->sdf = 0;
+ /*
+ * The sidad field (for sdf == 2) is now the gbea field (for sdf == 0).
+ * Use the reset value of gbea to avoid leaking the kernel pointer of
+ * the just freed sida.
+ */
+ vcpu->arch.sie_block->gbea = 1;
+ kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu);
+}
+
int kvm_s390_pv_destroy_cpu(struct kvm_vcpu *vcpu, u16 *rc, u16 *rrc)
{
int cc;
@@ -258,24 +276,9 @@ int kvm_s390_pv_destroy_cpu(struct kvm_vcpu *vcpu, u16 *rc, u16 *rrc)
WARN_ONCE(cc, "protvirt destroy cpu failed rc %x rrc %x", *rc, *rrc);
/* Intended memory leak for something that should never happen. */
- if (!cc)
- free_pages(vcpu->arch.pv.stor_base,
- get_order(uv_info.guest_cpu_stor_len));
-
- free_page((unsigned long)sida_addr(vcpu->arch.sie_block));
- vcpu->arch.sie_block->pv_handle_cpu = 0;
- vcpu->arch.sie_block->pv_handle_config = 0;
- memset(&vcpu->arch.pv, 0, sizeof(vcpu->arch.pv));
- vcpu->arch.sie_block->sdf = 0;
- /*
- * The sidad field (for sdf == 2) is now the gbea field (for sdf == 0).
- * Use the reset value of gbea to avoid leaking the kernel pointer of
- * the just freed sida.
- */
- vcpu->arch.sie_block->gbea = 1;
- kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu);
+ kvm_s390_pv_dispose_cpu(vcpu, !cc);
- return cc ? EIO : 0;
+ return cc ? -EIO : 0;
}
int kvm_s390_pv_create_cpu(struct kvm_vcpu *vcpu, u16 *rc, u16 *rrc)
@@ -319,9 +322,7 @@ int kvm_s390_pv_create_cpu(struct kvm_vcpu *vcpu, u16 *rc, u16 *rrc)
uvcb.header.rrc);
if (cc) {
- u16 dummy;
-
- kvm_s390_pv_destroy_cpu(vcpu, &dummy, &dummy);
+ kvm_s390_pv_dispose_cpu(vcpu, true);
return -EIO;
}
--
2.55.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH v3 01/10] KVM: s390: Fix unlikely NULL gmap dereference
2026-07-27 15:02 ` [PATCH v3 01/10] KVM: s390: Fix unlikely NULL gmap dereference Claudio Imbrenda
@ 2026-07-27 15:24 ` sashiko-bot
0 siblings, 0 replies; 21+ messages in thread
From: sashiko-bot @ 2026-07-27 15:24 UTC (permalink / raw)
To: Claudio Imbrenda
Cc: Vasily Gorbik, kvm, linux-s390, Heiko Carstens, Alexander Gordeev
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Missing compiler barrier in vCPU initialization publication allows compiler reordering, potentially defeating the NULL pointer dereference fix.
--
--- Patch [1]: [PATCH v3 01/10] KVM: s390: Fix unlikely NULL gmap dereference ---
commit 5328cd0469f8706fce5babcef6c93d98cfcef985
Author: Claudio Imbrenda <imbrenda@linux.ibm.com>
KVM: s390: Fix unlikely NULL gmap dereference
This commit fixes a potential NULL pointer dereference if a malicious
userspace program guesses a newly created vCPU file descriptor and
starts it before kvm_arch_vcpu_postcreate() finishes. It adds an
initialized flag that is checked before allowing vCPU ioctls to run.
> diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
> index 23c817595e28d..eff0644b8517d 100644
> --- a/arch/s390/kvm/kvm-s390.c
> +++ b/arch/s390/kvm/kvm-s390.c
> @@ -3611,6 +3611,8 @@ void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu)
> if (test_kvm_facility(vcpu->kvm, 74) || vcpu->kvm->arch.user_instr0 ||
> vcpu->kvm->arch.user_operexec)
> vcpu->arch.sie_block->ictl |= ICTL_OPEREXC;
> +
> + WRITE_ONCE(vcpu->arch.initialized, true);
[Severity: High]
Could the compiler reorder the gmap assignment after this WRITE_ONCE()?
Since WRITE_ONCE() only guarantees volatile access but does not provide a
general compiler barrier, it might be possible for the compiler to legally
reorder the preceding non-volatile store (vcpu->arch.gmap = ...) to occur
after the initialized flag is set.
If this happens, a concurrent thread could read initialized as true but
still observe a NULL gmap in __vcpu_run(), triggering the exact crash this
patch intends to fix.
Would it be safer to use smp_store_release() here to ensure the gmap
initialization is safely published?
> }
>
> static bool kvm_has_pckmo_subfunc(struct kvm *kvm, unsigned long nr)
[ ... ]
> @@ -5037,6 +5039,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
> kvm_run->kvm_dirty_regs & ~KVM_SYNC_S390_VALID_FIELDS)
> return -EINVAL;
>
> + if (!READ_ONCE(vcpu->arch.initialized))
> + return -EINVAL;
[Severity: High]
If smp_store_release() is used in kvm_arch_vcpu_postcreate(), would it make
sense to use smp_load_acquire() here to properly pair with it and guarantee
we observe the fully initialized vCPU state?
> +
> vcpu_load(vcpu);
>
> if (guestdbg_exit_pending(vcpu)) {
[ ... ]
> @@ -5521,6 +5526,9 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
> long r;
> u16 rc, rrc;
>
> + if (!READ_ONCE(vcpu->arch.initialized))
> + return -EINVAL;
[Severity: High]
Similarly, should this be smp_load_acquire() to ensure memory visibility
guarantees match across all the vCPU ioctl paths?
> +
> vcpu_load(vcpu);
>
> switch (ioctl) {
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260727150254.236021-1-imbrenda@linux.ibm.com?part=1
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v3 02/10] KVM: s390: Fix leaking of PGM_ADDRESSING to userspace
2026-07-27 15:02 ` [PATCH v3 02/10] KVM: s390: Fix leaking of PGM_ADDRESSING to userspace Claudio Imbrenda
@ 2026-07-27 15:33 ` sashiko-bot
0 siblings, 0 replies; 21+ messages in thread
From: sashiko-bot @ 2026-07-27 15:33 UTC (permalink / raw)
To: Claudio Imbrenda
Cc: linux-s390, Vasily Gorbik, kvm, Heiko Carstens, Alexander Gordeev
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] This problem wasn't introduced by this patch, but the `kvm_s390_set_skeys` ioctl handler contains an O(N^2) retry loop that executes with preemption disabled, which can trigger a hard lockup or RCU stall.
--
--- Patch [2]: [PATCH v3 02/10] KVM: s390: Fix leaking of PGM_ADDRESSING to userspace ---
commit 175d33190557729485ae32f46f8a61bb29680d52
Author: Claudio Imbrenda <imbrenda@linux.ibm.com>
KVM: s390: Fix leaking of PGM_ADDRESSING to userspace
This commit fixes an issue where kvm_s390_set_cmma_bits() and several
storage key operations return positive error values (like PGM_ADDRESSING)
to userspace instead of standard negative error codes. It updates the
return logic to convert these positive values to -EFAULT.
> diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
> index eff0644b8517d..8b7e7da354a25 100644
> --- a/arch/s390/kvm/kvm-s390.c
> +++ b/arch/s390/kvm/kvm-s390.c
[ ... ]
> @@ -2274,7 +2274,7 @@ static int kvm_s390_set_skeys(struct kvm *kvm, struct kvm_s390_skeys *args)
[Severity: High]
This isn't a bug introduced by this patch, but looking at the loop just
above this return statement in kvm_s390_set_skeys():
do {
r = kvm_s390_mmu_cache_topup(mc);
if (r == -ENOMEM)
break;
scoped_guard(read_lock, &kvm->mmu_lock) {
for (i = 0 ; i < args->count; i++) {
r = dat_set_storage_key(mc, kvm->arch.gmap->asce,
args->start_gfn + i, keys[i], 0);
if (r)
break;
}
}
} while (r == -ENOMEM);
Can this loop trigger a hard lockup or RCU stall?
When dat_set_storage_key() depletes the MMU cache and returns -ENOMEM, the
inner loop breaks. The outer loop will then refill the cache and restart
the inner loop completely from i = 0.
For large unmapped memory ranges, does this result in O(N^2) behavior where
the kernel re-traverses previously mapped pages over and over?
Since this entire process happens under scoped_guard(read_lock, &kvm->mmu_lock)
which disables preemption, an unprivileged guest calling KVM_S390_SET_SKEYS
with a large count could potentially cause a local denial of service.
> kvm_s390_free_mmu_cache(mc);
> out:
> kvfree(keys);
> - return r;
> + return r <= 0 ? r : -EFAULT;
> }
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260727150254.236021-1-imbrenda@linux.ibm.com?part=2
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v3 03/10] KVM: s390: Fix race in __do_essa()
2026-07-27 15:02 ` [PATCH v3 03/10] KVM: s390: Fix race in __do_essa() Claudio Imbrenda
@ 2026-07-27 15:43 ` sashiko-bot
0 siblings, 0 replies; 21+ messages in thread
From: sashiko-bot @ 2026-07-27 15:43 UTC (permalink / raw)
To: Claudio Imbrenda
Cc: kvm, Heiko Carstens, Vasily Gorbik, linux-s390, Alexander Gordeev
> An unlikely race between __do_essa() and kvm_s390_vm_start_migration(),
> kvm_s390_vm_stop_migration(), or dat_get_cmma() was possible.
>
> Fix by locking kvm->slots_lock. Since this is not a hot path, the
> overhead of an additional mutex is negligible.
>
> Fixes: e38c884df921 ("KVM: s390: Switch to new gmap")
> Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260727150254.236021-1-imbrenda@linux.ibm.com?part=3
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v3 04/10] KVM: s390: cmma: Fix dirty tracking when removing memslot
2026-07-27 15:02 ` [PATCH v3 04/10] KVM: s390: cmma: Fix dirty tracking when removing memslot Claudio Imbrenda
@ 2026-07-27 16:03 ` sashiko-bot
0 siblings, 0 replies; 21+ messages in thread
From: sashiko-bot @ 2026-07-27 16:03 UTC (permalink / raw)
To: Claudio Imbrenda
Cc: Alexander Gordeev, kvm, linux-s390, Heiko Carstens, Vasily Gorbik
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
New issues:
- [Critical] Unconditional NULL pointer dereference of the `old` memslot during `KVM_MR_CREATE` when migration mode is active.
- [Low] Build failure due to `goto` jumping over a `guard()` declaration, violating C cleanup attribute semantics.
Pre-existing issues:
- [High] Memory exhaustion and guest memory corruption during `KVM_MR_MOVE` due to shared MMU cache.
--
--- Patch [4]: [PATCH v3 04/10] KVM: s390: cmma: Fix dirty tracking when removing memslot ---
commit bf34c670340b7779837adadb9e6857c53511481a
Author: Claudio Imbrenda <imbrenda@linux.ibm.com>
KVM: s390: cmma: Fix dirty tracking when removing memslot
This patch updates CMMA dirty tracking to decrement the counter when a
memslot is removed. It walks the memslot's GFN range during
kvm_arch_commit_memory_region to clear the dirty count.
> diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
> index e154a8ad6c735..0a44351722702 100644
> --- a/arch/s390/kvm/kvm-s390.c
> +++ b/arch/s390/kvm/kvm-s390.c
[ ... ]
> @@ -5817,7 +5825,15 @@ void kvm_arch_commit_memory_region(struct kvm *kvm,
> goto out;
> }
[Severity: Low]
Will this compile correctly? The goto statement here jumps over the guard()
declaration below, which typically causes a compiler error since C
restricts jumping past the initialization of __attribute__((cleanup))
variables.
>
> + guard(mutex)(&kvm->slots_arch_lock);
> +
> scoped_guard(write_lock, &kvm->mmu_lock) {
> + if (kvm->arch.migration_mode && kvm->arch.use_cmma) {
> + _dat_walk_gfn_range(old->base_gfn, old->base_gfn + old->npages,
[Severity: Critical]
Can this code trigger a NULL pointer dereference when a new memory slot is
created?
If change == KVM_MR_CREATE, the old memslot pointer is NULL, but this
block unconditionally dereferences old->base_gfn and old->npages before
the switch statement checks the change type.
> + kvm->arch.gmap->asce, &ops, DAT_WALK_IGN_HOLES,
> + &kvm->arch.cmma_dirty_pages);
> + }
> +
> switch (change) {
> case KVM_MR_DELETE:
> rc = dat_delete_slot(mc, kvm->arch.gmap->asce, old->base_gfn, old->npages);
[Severity: High]
This is a pre-existing issue, but could this lead to memory exhaustion and
guest memory corruption during KVM_MR_MOVE?
Looking at the KVM_MR_MOVE case below this in kvm_arch_commit_memory_region():
case KVM_MR_MOVE:
rc = dat_delete_slot(mc, kvm->arch.gmap->asce, old->base_gfn, old->npages);
if (rc)
break;
fallthrough;
case KVM_MR_CREATE:
rc = dat_create_slot(mc, kvm->arch.gmap->asce, new->base_gfn, new->npages);
The code falls through from dat_delete_slot() to dat_create_slot() and
shares the single kvm_s390_mmu_cache (mc). If the cache runs out of space
for the second operation, it will fail midway, leaving the DAT tables out
of sync with the memslots since this function cannot return an error to
userspace.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260727150254.236021-1-imbrenda@linux.ibm.com?part=4
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v3 05/10] KVM: s390: ucontrol: Add missing locking around gmap_remove_child()
2026-07-27 15:02 ` [PATCH v3 05/10] KVM: s390: ucontrol: Add missing locking around gmap_remove_child() Claudio Imbrenda
@ 2026-07-27 16:14 ` sashiko-bot
0 siblings, 0 replies; 21+ messages in thread
From: sashiko-bot @ 2026-07-27 16:14 UTC (permalink / raw)
To: Claudio Imbrenda
Cc: Heiko Carstens, kvm, Vasily Gorbik, Alexander Gordeev, linux-s390
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [Critical] Unconditional free of physical page 0 on error path in kvm_s390_vcpu_setup() when CMMA is disabled.
--
--- Patch [5]: [PATCH v3 05/10] KVM: s390: ucontrol: Add missing locking around gmap_remove_child() ---
commit 23ca669df08a6ebee3b62a02dbada5159020162e
Author: Claudio Imbrenda <imbrenda@linux.ibm.com>
KVM: s390: ucontrol: Add missing locking around gmap_remove_child()
gmap_remove_child() needs to be called while holding the children_lock
of the parent gmap. This was not the case in the error handling path of
kvm_arch_vcpu_create() for UCONTROL guests.
> diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
> index 0a44351722702..e2a15799b9ac3 100644
> --- a/arch/s390/kvm/kvm-s390.c
> +++ b/arch/s390/kvm/kvm-s390.c
> @@ -3867,7 +3867,9 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
>
> out_ucontrol_uninit:
[Severity: Critical]
This is a pre-existing issue, but is it possible for the error handling path
in kvm_s390_vcpu_setup() to accidentally free physical page 0?
In kvm_s390_vcpu_setup(), if use_cmma is 0, kvm_s390_vcpu_setup_cmma() is
skipped and vcpu->arch.sie_block->cbrlo is left at its initialized value
of 0.
If a subsequent step like kvm_s390_pv_create_cpu() fails, the error path
unconditionally triggers the CMMA cleanup:
arch/s390/kvm/kvm-s390.c:kvm_s390_vcpu_setup() {
...
if (rc)
goto out_free_cpu;
...
out_free_cpu:
kvm_s390_vcpu_unsetup_cmma(vcpu);
...
}
Inside kvm_s390_vcpu_unsetup_cmma(), the page is freed without checking if
CMMA was actually initialized:
arch/s390/kvm/kvm-s390.c:kvm_s390_vcpu_unsetup_cmma() {
...
free_page((unsigned long)phys_to_virt(vcpu->arch.sie_block->cbrlo));
...
}
On s390, phys_to_virt(0) evaluates to __identity_base. When KASLR is enabled,
this is a non-zero virtual address that maps exactly to physical page 0.
Because the resulting virtual address is non-zero, it bypasses the addr != 0
safeguard in free_pages(), which could cause physical page 0 (containing
s390 lowcore data) to be freed into the buddy allocator.
Would it make sense to verify use_cmma is enabled or that cbrlo is non-zero
before freeing this page?
> if (kvm_is_ucontrol(vcpu->kvm)) {
> + spin_lock(&vcpu->kvm->arch.gmap->children_lock);
> gmap_remove_child(vcpu->arch.gmap);
> + spin_unlock(&vcpu->kvm->arch.gmap->children_lock);
> vcpu->arch.gmap = gmap_put(vcpu->arch.gmap);
> }
> out_free_sie_block:
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260727150254.236021-1-imbrenda@linux.ibm.com?part=5
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v3 06/10] KVM: s390: Fix overclearing ESCA in case of error
2026-07-27 15:02 ` [PATCH v3 06/10] KVM: s390: Fix overclearing ESCA in case of error Claudio Imbrenda
@ 2026-07-27 16:33 ` sashiko-bot
0 siblings, 0 replies; 21+ messages in thread
From: sashiko-bot @ 2026-07-27 16:33 UTC (permalink / raw)
To: Claudio Imbrenda
Cc: Alexander Gordeev, Vasily Gorbik, linux-s390, Heiko Carstens, kvm
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] For UCONTROL VMs, the ESCA block CPU array is accessed out of bounds because vCPU IDs up to 254 are permitted, exceeding the array's size of 248.
--
--- Patch [6]: [PATCH v3 06/10] KVM: s390: Fix overclearing ESCA in case of error ---
commit 711c5a0b8c8ac3214d997bede21c76e30e58d712
Author: Claudio Imbrenda <imbrenda@linux.ibm.com>
KVM: s390: Fix overclearing ESCA in case of error
This commit modifies vCPU destruction to skip clearing the ESCA entry if
the vCPU was not successfully initialized.
> diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
> index 9e3e6b0d72ad6..2acdff130fa6c 100644
> --- a/arch/s390/kvm/interrupt.c
> +++ b/arch/s390/kvm/interrupt.c
> @@ -86,7 +86,7 @@ static void sca_clear_ext_call(struct kvm_vcpu *vcpu)
> struct esca_block *sca = vcpu->kvm->arch.sca;
> union esca_sigp_ctrl *sigp_ctrl = &sca->cpu[vcpu->vcpu_id].sigp_ctrl;
>
> - if (!kvm_s390_use_sca_entries())
> + if (!kvm_s390_use_sca_entries() || !vcpu->arch.initialized)
> return;
> kvm_s390_clear_cpuflags(vcpu, CPUSTAT_ECALL_PEND);
>
> WRITE_ONCE(sigp_ctrl->value, 0);
[Severity: High]
This is a pre-existing issue, but does this code write past the bounds of
the esca_block allocation for UCONTROL VMs?
Looking at kvm_arch_vcpu_precreate() in arch/s390/kvm/kvm-s390.c, the
bounds check for ESCA CPU slots is explicitly bypassed for UCONTROL VMs:
if (!kvm_is_ucontrol(kvm) && !sca_can_add_vcpu(kvm, id))
return -EINVAL;
This allows vCPU IDs up to 254. However, the ESCA block CPU array only has
248 slots, and the block itself is allocated as exactly 4 pages.
When destroying a vCPU with an ID >= 248, the write operation in this
function appears to access memory past the end of the esca_block.
A similar situation seems to happen in sca_inject_ext_call() when
processing external calls:
arch/s390/kvm/interrupt.c:sca_inject_ext_call() {
...
union esca_sigp_ctrl *sigp_ctrl = &sca->cpu[vcpu->vcpu_id].sigp_ctrl;
...
rc = cmpxchg(&sigp_ctrl->value, old_val.value, new_val.value);
...
}
Could this lead to kernel memory corruption if a UCONTROL VM is created
with large vCPU IDs?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260727150254.236021-1-imbrenda@linux.ibm.com?part=6
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v3 07/10] KVM: s390: Return -EINTR if a signal was pending while faulting-in
2026-07-27 15:02 ` [PATCH v3 07/10] KVM: s390: Return -EINTR if a signal was pending while faulting-in Claudio Imbrenda
@ 2026-07-27 16:59 ` sashiko-bot
0 siblings, 0 replies; 21+ messages in thread
From: sashiko-bot @ 2026-07-27 16:59 UTC (permalink / raw)
To: Claudio Imbrenda
Cc: Heiko Carstens, Vasily Gorbik, Alexander Gordeev, linux-s390, kvm
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] The `handle_mvpg_pei` function incorrectly leaks positive program exception codes (e.g., PGM_ADDRESSING) to userspace through the KVM_RUN ioctl, instead of injecting them into the guest.
--
--- Patch [7]: [PATCH v3 07/10] KVM: s390: Return -EINTR if a signal was pending while faulting-in ---
commit d199a77e2748da899d6f673aade7f1a0a260ebe8
Author: Claudio Imbrenda <imbrenda@linux.ibm.com>
KVM: s390: Return -EINTR if a signal was pending while faulting-in
If a signal is pending while trying to fault-in a page, return -EINTR
instead of -EAGAIN.
> diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c
> index 1980df61ef304..08f2128db1473 100644
> --- a/arch/s390/kvm/intercept.c
> +++ b/arch/s390/kvm/intercept.c
> @@ -369,27 +369,25 @@ static int handle_mvpg_pei(struct kvm_vcpu *vcpu)
[ ... ]
> rc = guest_translate_address_with_key(vcpu, vcpu->run->s.regs.gprs[reg1],
> reg1, &dstaddr, GACC_STORE, 0);
> if (rc)
> return kvm_s390_inject_prog_cond(vcpu, rc);
>
> + kvm_s390_retry_instr(vcpu);
> +
> do {
> - rc = kvm_s390_faultin_gfn_simple(vcpu, NULL, gpa_to_gfn(dstaddr), true);
> + rc = kvm_s390_faultin_gfn_simple(vcpu, NULL, gpa_to_gfn(srcaddr), false);
> } while (rc == -EAGAIN);
> if (rc)
> return rc;
[Severity: High]
This is a pre-existing issue, but does this leak positive program exception
codes to userspace instead of injecting them into the guest?
If a guest executes an MVPG instruction with an unmapped guest address,
kvm_s390_faultin_gfn_simple() can return PGM_ADDRESSING (which is 5).
Because this positive value is returned directly instead of passing it
through kvm_s390_inject_prog_cond(), it appears to propagate all the way up
to the KVM_RUN ioctl return.
Userspace VMMs like QEMU might not update run->exit_reason on a positive
return code, potentially leading to stale exit reasons and state corruption,
and the guest is denied the architectural program exception it is owed.
Should this be wrapped in kvm_s390_inject_prog_cond(vcpu, rc) instead?
> - kvm_s390_retry_instr(vcpu);
> + do {
> + rc = kvm_s390_faultin_gfn_simple(vcpu, NULL, gpa_to_gfn(dstaddr), true);
> + } while (rc == -EAGAIN);
>
> - return 0;
> + return rc;
[Severity: High]
This is also a pre-existing issue for the same reason. Does the destination
fault-in need the same kvm_s390_inject_prog_cond() wrapper to prevent
positive program exception codes from leaking to userspace?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260727150254.236021-1-imbrenda@linux.ibm.com?part=7
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v3 08/10] KVM: s390: Free the mmu cache when kvm_arch_vcpu_create() fails
2026-07-27 15:02 ` [PATCH v3 08/10] KVM: s390: Free the mmu cache when kvm_arch_vcpu_create() fails Claudio Imbrenda
@ 2026-07-27 17:06 ` sashiko-bot
0 siblings, 0 replies; 21+ messages in thread
From: sashiko-bot @ 2026-07-27 17:06 UTC (permalink / raw)
To: Claudio Imbrenda
Cc: linux-s390, Vasily Gorbik, Alexander Gordeev, kvm, Heiko Carstens
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] Mixing goto-based error handling with scope-based cleanup (__free) in the same function.
--
--- Patch [8]: [PATCH v3 08/10] KVM: s390: Free the mmu cache when kvm_arch_vcpu_create() fails ---
commit f957b5e2634eaa5f53bf929349c916ffa15d9f2c
Author: Claudio Imbrenda <imbrenda@linux.ibm.com>
KVM: s390: Free the mmu cache when kvm_arch_vcpu_create() fails
This commit switches kvm_arch_vcpu_create() to use the __free()
scope-based cleanup helper for the mmu cache to prevent memory leaks
during initialization failures.
> diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
> --- a/arch/s390/kvm/kvm-s390.c
> +++ b/arch/s390/kvm/kvm-s390.c
> @@ -3794,19 +3794,17 @@ int kvm_arch_vcpu_precreate(struct kvm *kvm, unsigned int id)
>
> int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
> {
> + struct kvm_s390_mmu_cache *mc __free(kvm_s390_mmu_cache) = NULL;
> struct sie_page *sie_page;
> int rc;
[ ... ]
> @@ -3862,6 +3860,8 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
> if (rc)
> goto out_ucontrol_uninit;
>
[Severity: Low]
Are we permitted to mix scope-based cleanup and goto-based error handling
in the same function?
The cleanup guidelines indicate that for a given routine, we should generally
convert all resources that need a goto cleanup to scope-based cleanup, or
convert none of them. Mixing __free() with existing goto paths can create
confusing ownership semantics during future refactoring.
Could we either convert out_ucontrol_uninit and out_free_sie_block to use
scope-based cleanup as well, or stick to traditional goto labels for freeing
the mmu cache?
> + vcpu->arch.mc = mc;
> + mc = NULL;
> kvm_s390_update_topology_change_report(vcpu->kvm, 1);
> return 0;
>
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260727150254.236021-1-imbrenda@linux.ibm.com?part=8
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v3 09/10] KVM: s390: Fix ordering when adding to SCA
2026-07-27 15:02 ` [PATCH v3 09/10] KVM: s390: Fix ordering when adding to SCA Claudio Imbrenda
@ 2026-07-27 17:12 ` sashiko-bot
0 siblings, 0 replies; 21+ messages in thread
From: sashiko-bot @ 2026-07-27 17:12 UTC (permalink / raw)
To: Claudio Imbrenda
Cc: Vasily Gorbik, kvm, linux-s390, Heiko Carstens, Alexander Gordeev
> When adding a new vCPU to the SCA area, the validity bit in the MCN was
> set before the pointer to the state description, potentially allowing
> for a race.
>
> Fix by setting the pointer before setting the bit.
>
> Fixes: 14542a0a54c5 ("KVM: S390: Remove sca_lock")
> Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260727150254.236021-1-imbrenda@linux.ibm.com?part=9
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v3 10/10] KVM: s390: Fix cleanup in kvm_s390_pv_create_cpu()
2026-07-27 15:02 ` [PATCH v3 10/10] KVM: s390: Fix cleanup in kvm_s390_pv_create_cpu() Claudio Imbrenda
@ 2026-07-27 17:18 ` sashiko-bot
0 siblings, 0 replies; 21+ messages in thread
From: sashiko-bot @ 2026-07-27 17:18 UTC (permalink / raw)
To: Claudio Imbrenda
Cc: Vasily Gorbik, Heiko Carstens, kvm, Alexander Gordeev, linux-s390
> If creating a protected vCPU in kvm_s390_pv_create_cpu() fails,
> kvm_s390_pv_destroy_cpu() was called, which checks whether the vCPU has
> a PV handle and exits doing nothing otherwise. At that point, due to
> not having created the protected vCPU, the PV handle will not be set,
> and kvm_s390_pv_destroy_cpu() will do nothing, thus leaking the
> allocated memory.
>
> Fix by factoring out the code to free and reset a PV vCPU; call it from
> kvm_s390_pv_destroy_cpu() and kvm_s390_pv_create_cpu().
>
> Fixes: d4074324b07a ("KVM: s390: pv: avoid double free of sida page")
> Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260727150254.236021-1-imbrenda@linux.ibm.com?part=10
^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2026-07-27 17:18 UTC | newest]
Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-27 15:02 [PATCH v3 00/10] KVM: s390: Misc fixes Claudio Imbrenda
2026-07-27 15:02 ` [PATCH v3 01/10] KVM: s390: Fix unlikely NULL gmap dereference Claudio Imbrenda
2026-07-27 15:24 ` sashiko-bot
2026-07-27 15:02 ` [PATCH v3 02/10] KVM: s390: Fix leaking of PGM_ADDRESSING to userspace Claudio Imbrenda
2026-07-27 15:33 ` sashiko-bot
2026-07-27 15:02 ` [PATCH v3 03/10] KVM: s390: Fix race in __do_essa() Claudio Imbrenda
2026-07-27 15:43 ` sashiko-bot
2026-07-27 15:02 ` [PATCH v3 04/10] KVM: s390: cmma: Fix dirty tracking when removing memslot Claudio Imbrenda
2026-07-27 16:03 ` sashiko-bot
2026-07-27 15:02 ` [PATCH v3 05/10] KVM: s390: ucontrol: Add missing locking around gmap_remove_child() Claudio Imbrenda
2026-07-27 16:14 ` sashiko-bot
2026-07-27 15:02 ` [PATCH v3 06/10] KVM: s390: Fix overclearing ESCA in case of error Claudio Imbrenda
2026-07-27 16:33 ` sashiko-bot
2026-07-27 15:02 ` [PATCH v3 07/10] KVM: s390: Return -EINTR if a signal was pending while faulting-in Claudio Imbrenda
2026-07-27 16:59 ` sashiko-bot
2026-07-27 15:02 ` [PATCH v3 08/10] KVM: s390: Free the mmu cache when kvm_arch_vcpu_create() fails Claudio Imbrenda
2026-07-27 17:06 ` sashiko-bot
2026-07-27 15:02 ` [PATCH v3 09/10] KVM: s390: Fix ordering when adding to SCA Claudio Imbrenda
2026-07-27 17:12 ` sashiko-bot
2026-07-27 15:02 ` [PATCH v3 10/10] KVM: s390: Fix cleanup in kvm_s390_pv_create_cpu() Claudio Imbrenda
2026-07-27 17:18 ` sashiko-bot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox