* [PATCHv2 1/7] KVM: PPC: Book3S HV: Read EX_DSISR as a 32-bit field on guest exit
2026-11-01 14:46 [PATCHv2 0/7] KVM: PPC: Misc fixes and nestedv2 vCPU limit fixes Ritesh Harjani (IBM)
@ 2026-11-01 14:46 ` Ritesh Harjani (IBM)
2026-11-01 14:46 ` [PATCHv2 2/7] KVM: PPC: Book3S: Don't call __ffs() on an empty pending_exceptions bitmap Ritesh Harjani (IBM)
` (5 subsequent siblings)
6 siblings, 0 replies; 11+ messages in thread
From: Ritesh Harjani (IBM) @ 2026-11-01 14:46 UTC (permalink / raw)
To: linuxppc-dev
Cc: Madhavan Srinivasan, Venkat Rao Bagalkote, linux-kernel, chleroy,
Michael Ellerman, Nicholas Piggin, kvm, Anushree Mathur,
Harsh Prateek Bora, Ritesh Harjani (IBM)
kvmhv_vcpu_entry_p9() recovers the guest fault state from the paca
exception save area with
vcpu->arch.fault_dsisr = exsave[EX_DSISR/sizeof(u64)];
but EX_DSISR is not a doubleword. It is a 32-bit field at offset 48 that
shares a doubleword with EX_CCR at offset 52 and the exception entry in
exceptions-64s.S stores it accordingly. For e.g.
stw r10,IAREA+EX_DSISR(r13)
This issue was caught when running kvm selftests on big-endian, where
this read would land in the high half and the truncation yields EX_CCR
instead - KVM acts on the guest's condition register as if it were
HDSISR.
The result is that every HDSI on a big-endian host is evaluated against a
bogus fault status i.e. it fails with below error:
KVM: Got radix HV page fault with DSISR=84004840
Let's fix this by reading this field at it's natural width.
Fixes: 89d35b239101 ("KVM: PPC: Book3S HV P9: Implement the rest of the P9 path in C")
Signed-off-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
---
arch/powerpc/kvm/book3s_hv_p9_entry.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/kvm/book3s_hv_p9_entry.c b/arch/powerpc/kvm/book3s_hv_p9_entry.c
index 34bc0a8a1288..16aa8582b888 100644
--- a/arch/powerpc/kvm/book3s_hv_p9_entry.c
+++ b/arch/powerpc/kvm/book3s_hv_p9_entry.c
@@ -529,6 +529,15 @@ unsigned long kvmppc_msr_hard_disable_set_facilities(struct kvm_vcpu *vcpu, unsi
}
EXPORT_SYMBOL_GPL(kvmppc_msr_hard_disable_set_facilities);
+/*
+ * EX_DSISR is a 32-bit field that shares a doubleword with EX_CCR.
+ * Small helper for reading it back at its natural width.
+ */
+static u32 exsave_dsisr(u64 *exsave)
+{
+ return *(u32 *)((void *)exsave + EX_DSISR);
+}
+
int kvmhv_vcpu_entry_p9(struct kvm_vcpu *vcpu, u64 time_limit, unsigned long lpcr, u64 *tb)
{
struct p9_host_os_sprs host_os_sprs;
@@ -770,7 +779,7 @@ int kvmhv_vcpu_entry_p9(struct kvm_vcpu *vcpu, u64 time_limit, unsigned long lpc
if (unlikely(trap == BOOK3S_INTERRUPT_MACHINE_CHECK)) {
vcpu->arch.fault_dar = exsave[EX_DAR/sizeof(u64)];
- vcpu->arch.fault_dsisr = exsave[EX_DSISR/sizeof(u64)];
+ vcpu->arch.fault_dsisr = exsave_dsisr(exsave);
kvmppc_realmode_machine_check(vcpu);
} else if (unlikely(trap == BOOK3S_INTERRUPT_HMI)) {
@@ -781,7 +790,7 @@ int kvmhv_vcpu_entry_p9(struct kvm_vcpu *vcpu, u64 time_limit, unsigned long lpc
} else if (trap == BOOK3S_INTERRUPT_H_DATA_STORAGE) {
vcpu->arch.fault_dar = exsave[EX_DAR/sizeof(u64)];
- vcpu->arch.fault_dsisr = exsave[EX_DSISR/sizeof(u64)];
+ vcpu->arch.fault_dsisr = exsave_dsisr(exsave);
vcpu->arch.fault_gpa = mfspr(SPRN_ASDR);
} else if (trap == BOOK3S_INTERRUPT_H_INST_STORAGE) {
--
2.39.5
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCHv2 2/7] KVM: PPC: Book3S: Don't call __ffs() on an empty pending_exceptions bitmap
2026-11-01 14:46 [PATCHv2 0/7] KVM: PPC: Misc fixes and nestedv2 vCPU limit fixes Ritesh Harjani (IBM)
2026-11-01 14:46 ` [PATCHv2 1/7] KVM: PPC: Book3S HV: Read EX_DSISR as a 32-bit field on guest exit Ritesh Harjani (IBM)
@ 2026-11-01 14:46 ` Ritesh Harjani (IBM)
2026-11-01 14:53 ` sashiko-bot
2026-11-01 14:46 ` [PATCHv2 3/7] KVM: PPC: BookE: " Ritesh Harjani (IBM)
` (4 subsequent siblings)
6 siblings, 1 reply; 11+ messages in thread
From: Ritesh Harjani (IBM) @ 2026-11-01 14:46 UTC (permalink / raw)
To: linuxppc-dev
Cc: Madhavan Srinivasan, Venkat Rao Bagalkote, linux-kernel, chleroy,
Michael Ellerman, Nicholas Piggin, kvm, Anushree Mathur,
Harsh Prateek Bora, Ritesh Harjani (IBM)
This problem was caught when running KVM PPC selftests on big-endian.
__ffs() doc clearly says:
"Undefined if no bit exists, so code should check against 0 first"
This cause KVM to deliever an arbitrary interrupt to the guest and was
causing guest to hang up while running these selftests.
On checking further - GCC was emitting 0 in this case, which caused
System Reset in guest while running kvm selftests.
Use find_first_bit() instead, which reads the word once and returns the
bitmap size when no bit is set, instead of reading *pending twice
thereby causing TOCTOU as pointed by Sashiko.
Signed-off-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
---
arch/powerpc/kvm/book3s.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
index 2efbe05caed7..38816578d002 100644
--- a/arch/powerpc/kvm/book3s.c
+++ b/arch/powerpc/kvm/book3s.c
@@ -401,7 +401,7 @@ int kvmppc_core_prepare_to_enter(struct kvm_vcpu *vcpu)
if (vcpu->arch.pending_exceptions)
printk(KERN_EMERG "KVM: Check pending: %lx\n", vcpu->arch.pending_exceptions);
#endif
- priority = __ffs(*pending);
+ priority = find_first_bit(pending, BITS_PER_LONG * sizeof(*pending));
while (priority < BOOK3S_IRQPRIO_MAX) {
if (kvmppc_book3s_irqprio_deliver(vcpu, priority) &&
clear_irqprio(vcpu, priority)) {
--
2.39.5
^ permalink raw reply related [flat|nested] 11+ messages in thread* Re: [PATCHv2 2/7] KVM: PPC: Book3S: Don't call __ffs() on an empty pending_exceptions bitmap
2026-11-01 14:46 ` [PATCHv2 2/7] KVM: PPC: Book3S: Don't call __ffs() on an empty pending_exceptions bitmap Ritesh Harjani (IBM)
@ 2026-11-01 14:53 ` sashiko-bot
0 siblings, 0 replies; 11+ messages in thread
From: sashiko-bot @ 2026-11-01 14:53 UTC (permalink / raw)
To: Ritesh Harjani (IBM); +Cc: kvm
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] KVM: PPC: Book3S: out-of-bounds read in kvmppc_core_prepare_to_enter()
--
commit 05f5afe597ebfa07475ccb012aebebd6487a463b
Author: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
KVM: PPC: Book3S: Don't call __ffs() on an empty pending_exceptions bitmap
This commit replaces __ffs(*pending) with find_first_bit() in
kvmppc_core_prepare_to_enter() so that an empty pending_exceptions bitmap
does not invoke undefined behavior and deliver a bogus interrupt to the
guest.
> diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
> index 2efbe05caed76..38816578d002e 100644
> --- a/arch/powerpc/kvm/book3s.c
> +++ b/arch/powerpc/kvm/book3s.c
> @@ -401,7 +401,7 @@ int kvmppc_core_prepare_to_enter(struct kvm_vcpu *vcpu)
> if (vcpu->arch.pending_exceptions)
> printk(KERN_EMERG "KVM: Check pending: %lx\n", vcpu->arch.pending_exceptions);
> #endif
> - priority = __ffs(*pending);
> + priority = find_first_bit(pending, BITS_PER_LONG * sizeof(*pending));
[Severity: High]
Does passing BITS_PER_LONG * sizeof(*pending) as the bit size to
find_first_bit() in kvmppc_core_prepare_to_enter() (in
arch/powerpc/kvm/book3s.c) cause an out-of-bounds read past
vcpu->arch.pending_exceptions when no exceptions are pending?
vcpu->arch.pending_exceptions is a single unsigned long in struct
kvm_vcpu_arch (arch/powerpc/include/asm/kvm_host.h):
unsigned long pending_exceptions;
Because BITS_PER_LONG is already the number of bits in an unsigned long and
sizeof(*pending) is the byte size, BITS_PER_LONG * sizeof(*pending)
evaluates to 512 bits (8 unsigned longs) on 64-bit PowerPC or 128 bits (4
unsigned longs) on 32-bit PowerPC.
Since that size exceeds BITS_PER_LONG, small_const_nbits(size) in
find_first_bit() (include/linux/find.h) evaluates to false and calls
_find_first_bit() in lib/find_bit.c, which iterates across multiple words
and reads pending[1..7] (or pending[1..3]) out of bounds into adjacent
fields of struct kvm_vcpu_arch whenever vcpu->arch.pending_exceptions is 0.
Note that the find_next_bit() call later in the same loop uses
BITS_PER_BYTE:
priority = find_next_bit(pending,
BITS_PER_BYTE * sizeof(*pending),
priority + 1);
Should find_first_bit() use BITS_PER_BYTE * sizeof(*pending) (or simply
BITS_PER_LONG) here as well?
--
Sashiko AI review · https://sashiko.dev/#/patchset/b985cc12b0ed62599815ddf87e612bc8b6b2813c.1793543627.git.ritesh.list@gmail.com?part=1
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCHv2 3/7] KVM: PPC: BookE: Don't call __ffs() on an empty pending_exceptions bitmap
2026-11-01 14:46 [PATCHv2 0/7] KVM: PPC: Misc fixes and nestedv2 vCPU limit fixes Ritesh Harjani (IBM)
2026-11-01 14:46 ` [PATCHv2 1/7] KVM: PPC: Book3S HV: Read EX_DSISR as a 32-bit field on guest exit Ritesh Harjani (IBM)
2026-11-01 14:46 ` [PATCHv2 2/7] KVM: PPC: Book3S: Don't call __ffs() on an empty pending_exceptions bitmap Ritesh Harjani (IBM)
@ 2026-11-01 14:46 ` Ritesh Harjani (IBM)
2026-11-01 14:46 ` [PATCHv2 4/7] KVM: PPC: Book3S HV nestedv2: cap max vcpus to PAPR limit Ritesh Harjani (IBM)
` (3 subsequent siblings)
6 siblings, 0 replies; 11+ messages in thread
From: Ritesh Harjani (IBM) @ 2026-11-01 14:46 UTC (permalink / raw)
To: linuxppc-dev
Cc: Madhavan Srinivasan, Venkat Rao Bagalkote, linux-kernel, chleroy,
Michael Ellerman, Nicholas Piggin, kvm, Anushree Mathur,
Harsh Prateek Bora, Ritesh Harjani (IBM)
kvmppc_core_check_exceptions() has the same pattern as the Book3S code:
it starts the scan of the pending exception bitmap with
__ffs(*pending) and is called from kvmppc_core_prepare_to_enter() on
every guest entry, so it routinely passes 0 to __ffs(), which is
undefined.
To be safe here, let's use find_first_bit(), which returns the bitmap
size when no bit is set.
Signed-off-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
---
arch/powerpc/kvm/booke.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index 13ad4cf5fa71..9794ee6f7204 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -692,7 +692,7 @@ static void kvmppc_core_check_exceptions(struct kvm_vcpu *vcpu)
unsigned long *pending = &vcpu->arch.pending_exceptions;
unsigned int priority;
- priority = __ffs(*pending);
+ priority = find_first_bit(pending, BITS_PER_BYTE * sizeof(*pending));
while (priority < BOOKE_IRQPRIO_MAX) {
if (kvmppc_booke_irqprio_deliver(vcpu, priority))
break;
--
2.39.5
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCHv2 4/7] KVM: PPC: Book3S HV nestedv2: cap max vcpus to PAPR limit
2026-11-01 14:46 [PATCHv2 0/7] KVM: PPC: Misc fixes and nestedv2 vCPU limit fixes Ritesh Harjani (IBM)
` (2 preceding siblings ...)
2026-11-01 14:46 ` [PATCHv2 3/7] KVM: PPC: BookE: " Ritesh Harjani (IBM)
@ 2026-11-01 14:46 ` Ritesh Harjani (IBM)
2026-11-01 14:46 ` [PATCHv2 5/7] KVM: PPC: Book3S HV nestedv2: reject vCPU ids beyond the " Ritesh Harjani (IBM)
` (2 subsequent siblings)
6 siblings, 0 replies; 11+ messages in thread
From: Ritesh Harjani (IBM) @ 2026-11-01 14:46 UTC (permalink / raw)
To: linuxppc-dev
Cc: Madhavan Srinivasan, Venkat Rao Bagalkote, linux-kernel, chleroy,
Michael Ellerman, Nicholas Piggin, kvm, Anushree Mathur,
Harsh Prateek Bora, Ritesh Harjani (IBM)
PAPR spec for H_GUEST_CREATE_VCPU says:
"Only 2048 VCPUs can be created, and the specified ID must be in the range of 0
to 2047"
However, KVM reports KVM_CAP_MAX_VCPUS as NR_CPUS and KVM_CAP_MAX_VCPU_ID as
8 * NR_CPUS. It also passes the userspace vCPU id through to the hcall unchanged.
On a nestedv2 host (KVM on PowerVM / pseries nested PAPR) built with
NR_CPUS > 2048, kvm selftest e.g. kvm_create_max_vcpus will create vCPU
2048 and fail with EINVAL when the hypervisor returns H_P3.
Following error gets reported (with a debug print added to selftest to
print failed vcpu_id number):
./kvm_create_max_vcpus
Random seed: 0x6ec3f539
KVM_CAP_MAX_VCPU_ID: 65536
KVM_CAP_MAX_VCPUS: 8192
Testing creating 8192 vCPUs, with IDs 0...8191.
[ 62.655458][ T302] KVM: Create Guest vcpu hcall failed, rc=-56
[ 62.655458][ T302] KVM: Create Guest vcpu hcall failed, rc=-56
Failed KVM_CREATE_VCPU for vcpu_id 2048 with errno 22
==== Test Assertion Failure ====
lib/kvm_util.c:1395: vcpu->fd >= 0
pid=302 tid=302 errno=22 - Invalid argument
1 0x00000000100061d3: __vm_vcpu_add at kvm_util.c:1395 (discriminator 6)
2 0x0000000010001a6b: test_vcpu_creation at kvm_create_max_vcpus.c:32 (discriminator 3)
3 0x000000001000160b: main at kvm_create_max_vcpus.c:59
4 0x000000001001b713: __libc_start_call_main at libc-start.o:?
5 0x000000001001bb47: __libc_start_main_impl at ??:?
KVM_CREATE_VCPU failed, rc: -1 errno: 22 (Invalid argument)
[ 65.316986][ T302] KVM: TLB LPID invalidation hcall failed, rc=-2
[ 65.316986][ T302] KVM: TLB LPID invalidation hcall failed, rc=-2
Cap both extensions at 2048 when kvmhv_is_nestedv2() is set, so
userspace never requests an id the L0 cannot create. PowerNV and
nestedv1 are unchanged. The issue is only seen with nestedv2.
While at it, this also fixes the limit for KVM_CAP_NR_VCPUS.
Signed-off-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
---
arch/powerpc/include/asm/kvm_host.h | 1 +
arch/powerpc/kvm/powerpc.c | 6 ++++++
2 files changed, 7 insertions(+)
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index 708a32f89776..c068cc1dd51f 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -35,6 +35,7 @@
#define KVM_MAX_VCPUS NR_CPUS
#define KVM_MAX_VCORES NR_CPUS
+#define KVM_MAX_VCPU_IDS_NESTEDv2 2048 /* PAPR H_GUEST_CREATE_VCPU vcpuId */
#include <asm/cputhreads.h>
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 9194cf492d1c..cf620b6534de 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -663,12 +663,18 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
r = min(num_present_cpus(), KVM_MAX_VCPUS);
else
r = min(num_online_cpus(), KVM_MAX_VCPUS);
+ if (kvmhv_is_nestedv2())
+ r = min(r, KVM_MAX_VCPU_IDS_NESTEDv2);
break;
case KVM_CAP_MAX_VCPUS:
r = KVM_MAX_VCPUS;
+ if (kvmhv_is_nestedv2())
+ r = min(r, KVM_MAX_VCPU_IDS_NESTEDv2);
break;
case KVM_CAP_MAX_VCPU_ID:
r = KVM_MAX_VCPU_IDS;
+ if (kvmhv_is_nestedv2())
+ r = min(r, KVM_MAX_VCPU_IDS_NESTEDv2);
break;
#ifdef CONFIG_PPC_BOOK3S_64
case KVM_CAP_PPC_GET_SMMU_INFO:
--
2.39.5
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCHv2 5/7] KVM: PPC: Book3S HV nestedv2: reject vCPU ids beyond the PAPR limit
2026-11-01 14:46 [PATCHv2 0/7] KVM: PPC: Misc fixes and nestedv2 vCPU limit fixes Ritesh Harjani (IBM)
` (3 preceding siblings ...)
2026-11-01 14:46 ` [PATCHv2 4/7] KVM: PPC: Book3S HV nestedv2: cap max vcpus to PAPR limit Ritesh Harjani (IBM)
@ 2026-11-01 14:46 ` Ritesh Harjani (IBM)
2026-11-01 14:58 ` sashiko-bot
2026-11-01 14:46 ` [PATCHv2 6/7] KVM: PPC: Book3S HV: Fix error handling during vcore create Ritesh Harjani (IBM)
2026-11-01 14:46 ` [PATCHv2 7/7] KVM: PPC: Book3s: nestedv2: Free the guest state buffers if vcpu create fails Ritesh Harjani (IBM)
6 siblings, 1 reply; 11+ messages in thread
From: Ritesh Harjani (IBM) @ 2026-11-01 14:46 UTC (permalink / raw)
To: linuxppc-dev
Cc: Madhavan Srinivasan, Venkat Rao Bagalkote, linux-kernel, chleroy,
Michael Ellerman, Nicholas Piggin, kvm, Anushree Mathur,
Harsh Prateek Bora, Ritesh Harjani (IBM)
The previous patch caps KVM_CAP_MAX_VCPU_ID at 2048 on nestedv2 but
nothing actually enforces it. The generic KVM_CREATE_VCPU path only
checks the id against KVM_MAX_VCPU_IDS, which is 8 * NR_CPUS on HV.
That means a VMM that ignores the capability can still pass a larger id.
That id goes all the way down to H_GUEST_CREATE_VCPU, where the L0
rejects it and prints, ...
KVM: Create Guest vcpu hcall failed, rc=-56
...for every such attempt before failing the ioctl with -EINVAL anyway.
Check the id in kvm_arch_vcpu_precreate() instead so it fails early with
the same -EINVAL. Note that PowerNV and nestedv1 are not affected.
Signed-off-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
---
arch/powerpc/kvm/powerpc.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index cf620b6534de..5f9cfc34bec2 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -778,6 +778,9 @@ void kvm_arch_flush_shadow_memslot(struct kvm *kvm,
int kvm_arch_vcpu_precreate(struct kvm *kvm, unsigned int id)
{
+ if (kvmhv_is_nestedv2() && id >= KVM_MAX_VCPU_IDS_NESTEDv2)
+ return -EINVAL;
+
return 0;
}
--
2.39.5
^ permalink raw reply related [flat|nested] 11+ messages in thread* Re: [PATCHv2 5/7] KVM: PPC: Book3S HV nestedv2: reject vCPU ids beyond the PAPR limit
2026-11-01 14:46 ` [PATCHv2 5/7] KVM: PPC: Book3S HV nestedv2: reject vCPU ids beyond the " Ritesh Harjani (IBM)
@ 2026-11-01 14:58 ` sashiko-bot
0 siblings, 0 replies; 11+ messages in thread
From: sashiko-bot @ 2026-11-01 14:58 UTC (permalink / raw)
To: Ritesh Harjani (IBM); +Cc: kvm
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] KVM: PPC: undeclared KVM_MAX_VCPU_IDS_NESTEDv2 in kvm_arch_vcpu_precreate()
--
commit f56e9e3141b7693c524f0cc29414b94ab8a0b784
Author: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
KVM: PPC: Book3S HV nestedv2: reject vCPU ids beyond the PAPR limit
This commit adds a check in kvm_arch_vcpu_precreate() on Book3S HV nestedv2
to reject vCPU IDs at or above KVM_MAX_VCPU_IDS_NESTEDv2 with -EINVAL before
reaching the H_GUEST_CREATE_VCPU hcall.
> diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
> index 9194cf492d1ca..f82d3545b39ad 100644
> --- a/arch/powerpc/kvm/powerpc.c
> +++ b/arch/powerpc/kvm/powerpc.c
> @@ -772,6 +772,9 @@ void kvm_arch_flush_shadow_memslot(struct kvm *kvm,
>
> int kvm_arch_vcpu_precreate(struct kvm *kvm, unsigned int id)
> {
> + if (kvmhv_is_nestedv2() && id >= KVM_MAX_VCPU_IDS_NESTEDv2)
> + return -EINVAL;
[Severity: Medium]
Is this missing the prerequisite patch referenced in the commit message?
In arch/powerpc/kvm/powerpc.c, kvm_arch_vcpu_precreate() compares id against
KVM_MAX_VCPU_IDS_NESTEDv2, which is not defined anywhere in the tree, causing
compilation of arch/powerpc/kvm/powerpc.c to fail with an undeclared
identifier error.
In addition, kvm_vm_ioctl_check_extension() in arch/powerpc/kvm/powerpc.c
still returns KVM_MAX_VCPU_IDS unconditionally for KVM_CAP_MAX_VCPU_ID:
case KVM_CAP_MAX_VCPU_ID:
r = KVM_MAX_VCPU_IDS;
break;
rather than capping the capability at 2048 on nestedv2 as described in the
changelog.
--
Sashiko AI review · https://sashiko.dev/#/patchset/183d9a0e755f3735ebd531accb9c193cb40317ce.1793543627.git.ritesh.list@gmail.com?part=1
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCHv2 6/7] KVM: PPC: Book3S HV: Fix error handling during vcore create
2026-11-01 14:46 [PATCHv2 0/7] KVM: PPC: Misc fixes and nestedv2 vCPU limit fixes Ritesh Harjani (IBM)
` (4 preceding siblings ...)
2026-11-01 14:46 ` [PATCHv2 5/7] KVM: PPC: Book3S HV nestedv2: reject vCPU ids beyond the " Ritesh Harjani (IBM)
@ 2026-11-01 14:46 ` Ritesh Harjani (IBM)
2026-11-01 14:55 ` sashiko-bot
2026-11-01 14:46 ` [PATCHv2 7/7] KVM: PPC: Book3s: nestedv2: Free the guest state buffers if vcpu create fails Ritesh Harjani (IBM)
6 siblings, 1 reply; 11+ messages in thread
From: Ritesh Harjani (IBM) @ 2026-11-01 14:46 UTC (permalink / raw)
To: linuxppc-dev
Cc: Madhavan Srinivasan, Venkat Rao Bagalkote, linux-kernel, chleroy,
Michael Ellerman, Nicholas Piggin, kvm, Anushree Mathur,
Harsh Prateek Bora, Ritesh Harjani (IBM)
kvmppc_vcore_create() can fail and return NULL, this patch fixes the
error handling when this happens.
vcore and online_vcores count should only be updated when vcore was
actually created, otherwise it's state gets messed up for the VM run.
Signed-off-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
---
arch/powerpc/kvm/book3s_hv.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index 22283d46e8fe..7975e5de89d0 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -3090,10 +3090,12 @@ static int kvmppc_core_vcpu_create_hv(struct kvm_vcpu *vcpu)
err = -ENOMEM;
vcore = kvmppc_vcore_create(kvm,
id & ~(kvm->arch.smt_mode - 1));
- mutex_lock(&kvm->arch.mmu_setup_lock);
- kvm->arch.vcores[core] = vcore;
- kvm->arch.online_vcores++;
- mutex_unlock(&kvm->arch.mmu_setup_lock);
+ if (!vcore) {
+ mutex_lock(&kvm->arch.mmu_setup_lock);
+ kvm->arch.vcores[core] = vcore;
+ kvm->arch.online_vcores++;
+ mutex_unlock(&kvm->arch.mmu_setup_lock);
+ }
}
}
--
2.39.5
^ permalink raw reply related [flat|nested] 11+ messages in thread* Re: [PATCHv2 6/7] KVM: PPC: Book3S HV: Fix error handling during vcore create
2026-11-01 14:46 ` [PATCHv2 6/7] KVM: PPC: Book3S HV: Fix error handling during vcore create Ritesh Harjani (IBM)
@ 2026-11-01 14:55 ` sashiko-bot
0 siblings, 0 replies; 11+ messages in thread
From: sashiko-bot @ 2026-11-01 14:55 UTC (permalink / raw)
To: Ritesh Harjani (IBM); +Cc: kvm
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] KVM: PPC: Book3S HV: inverted vcore check in kvmppc_core_vcpu_create_hv()
--
commit 03a4203b0b5c05e6f77faafc6f01a945c2457b16
Author: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
KVM: PPC: Book3S HV: Fix error handling during vcore create
This commit adds a NULL check on the vcore returned by kvmppc_vcore_create()
in kvmppc_core_vcpu_create_hv() before updating kvm->arch.vcores[core] and
incrementing kvm->arch.online_vcores.
> diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
> index 22283d46e8fe6..7975e5de89d0e 100644
> --- a/arch/powerpc/kvm/book3s_hv.c
> +++ b/arch/powerpc/kvm/book3s_hv.c
> @@ -3090,10 +3090,12 @@ static int kvmppc_core_vcpu_create_hv(struct kvm_vcpu *vcpu)
> err = -ENOMEM;
> vcore = kvmppc_vcore_create(kvm,
> id & ~(kvm->arch.smt_mode - 1));
> - mutex_lock(&kvm->arch.mmu_setup_lock);
> - kvm->arch.vcores[core] = vcore;
> - kvm->arch.online_vcores++;
> - mutex_unlock(&kvm->arch.mmu_setup_lock);
> + if (!vcore) {
> + mutex_lock(&kvm->arch.mmu_setup_lock);
> + kvm->arch.vcores[core] = vcore;
> + kvm->arch.online_vcores++;
> + mutex_unlock(&kvm->arch.mmu_setup_lock);
> + }
[Severity: High]
Is the condition in if (!vcore) inverted here in
kvmppc_core_vcpu_create_hv()?
kvmppc_vcore_create() returns a non-NULL struct kvmppc_vcore pointer on
success and NULL on allocation failure, and kvmppc_core_vcpu_create_hv()
checks for failure immediately below:
if (!vcore)
return err;
With if (!vcore) guarding the mmu_setup_lock block, a successful
kvmppc_vcore_create() skips storing vcore in kvm->arch.vcores[core] and
incrementing kvm->arch.online_vcores, while still attaching the vcore to
vcpu->arch.vcore. Because kvmppc_free_vcores() frees vcores by iterating over
kvm->arch.vcores[], any allocated vcore will be leaked on VM teardown, and
callers relying on kvm->arch.vcores[] or kvm->arch.online_vcores (such as
sibling thread attachment, duplicate vCPU ID detection, kvmppc_update_lpcr(),
and kvmhv_set_smt_mode()) will see inconsistent state. Conversely, if
kvmppc_vcore_create() fails and returns NULL, kvm->arch.online_vcores is
incremented before returning -ENOMEM.
Should this check be if (vcore) instead?
--
Sashiko AI review · https://sashiko.dev/#/patchset/ca419693358e3af49b1dfa7887b34b8ef91a5daf.1793543627.git.ritesh.list@gmail.com?part=1
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCHv2 7/7] KVM: PPC: Book3s: nestedv2: Free the guest state buffers if vcpu create fails
2026-11-01 14:46 [PATCHv2 0/7] KVM: PPC: Misc fixes and nestedv2 vCPU limit fixes Ritesh Harjani (IBM)
` (5 preceding siblings ...)
2026-11-01 14:46 ` [PATCHv2 6/7] KVM: PPC: Book3S HV: Fix error handling during vcore create Ritesh Harjani (IBM)
@ 2026-11-01 14:46 ` Ritesh Harjani (IBM)
6 siblings, 0 replies; 11+ messages in thread
From: Ritesh Harjani (IBM) @ 2026-11-01 14:46 UTC (permalink / raw)
To: linuxppc-dev
Cc: Madhavan Srinivasan, Venkat Rao Bagalkote, linux-kernel, chleroy,
Michael Ellerman, Nicholas Piggin, kvm, Anushree Mathur,
Harsh Prateek Bora, Ritesh Harjani (IBM)
On a nestedv2 host, kvmppc_core_vcpu_create_hv() first creates the vCPU
in the L0 with kvmhv_nestedv2_vcpu_create(), which also allocates the
guest state messages and the run input/output buffers. Only after that
it picks a vcore for the vCPU - which can actually fail.
This patch therefore takes care of freeing the GSM abd GSB for nestedv2
if an error occurs later as part of the cleanup routine.
Signed-off-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
---
arch/powerpc/kvm/book3s_hv.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index 7975e5de89d0..a242abaea357 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -3099,8 +3099,11 @@ static int kvmppc_core_vcpu_create_hv(struct kvm_vcpu *vcpu)
}
}
- if (!vcore)
+ if (!vcore) {
+ if (kvmhv_is_nestedv2())
+ kvmhv_nestedv2_vcpu_free(vcpu, &vcpu->arch.nestedv2_io);
return err;
+ }
spin_lock(&vcore->lock);
++vcore->num_threads;
--
2.39.5
^ permalink raw reply related [flat|nested] 11+ messages in thread