* [PATCH 1/7] KVM: s390: Drop unused and unreachable kvm_arch_vcpu_should_kick()
2026-10-28 19:02 [PATCH 0/7] KVM: Ensure WAIT requests actually wait Sean Christopherson
@ 2026-10-28 19:02 ` Sean Christopherson
2026-11-02 15:32 ` Steffen Eiden
2026-10-28 19:02 ` [PATCH 2/7] KVM: Add a @force param to __kvm_vcpu_kick() for PPC backwards compatibility Sean Christopherson
` (5 subsequent siblings)
6 siblings, 1 reply; 13+ messages in thread
From: Sean Christopherson @ 2026-10-28 19:02 UTC (permalink / raw)
To: Marc Zyngier, Oliver Upton, Tianrui Zhao, Bibo Mao, Huacai Chen,
Madhavan Srinivasan, Anup Patel, Paul Walmsley, Palmer Dabbelt,
Albert Ou, Sean Christopherson, Paolo Bonzini
Cc: Fuad Tabba, Joey Gouly, Steffen Eiden, Suzuki K Poulose,
Zenghui Yu, Nicholas Piggin, Atish Patra, Alexandre Ghiti,
linux-arm-kernel, kvmarm, kvm, loongarch, linux-mips,
linuxppc-dev, kvm-riscv, linux-riscv, linux-kernel,
Stefan Teodorescu
Drop s390's kvm_arch_vcpu_should_kick() stub as the one and only call site
is wrapped with "#ifndef CONFIG_S390".
No functional change intended.
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
arch/s390/kvm/s390/s390.c | 7 -------
1 file changed, 7 deletions(-)
diff --git a/arch/s390/kvm/s390/s390.c b/arch/s390/kvm/s390/s390.c
index 18fb200f854a..9900a1a1c148 100644
--- a/arch/s390/kvm/s390/s390.c
+++ b/arch/s390/kvm/s390/s390.c
@@ -3922,13 +3922,6 @@ bool kvm_arch_no_poll(struct kvm_vcpu *vcpu)
return false;
}
-int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu)
-{
- /* kvm common code refers to this, but never calls it */
- BUG();
- return 0;
-}
-
static int kvm_arch_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu,
struct kvm_one_reg *reg)
{
--
2.56.0.313.g2479322e68-goog
^ permalink raw reply related [flat|nested] 13+ messages in thread* Re: [PATCH 1/7] KVM: s390: Drop unused and unreachable kvm_arch_vcpu_should_kick()
2026-10-28 19:02 ` [PATCH 1/7] KVM: s390: Drop unused and unreachable kvm_arch_vcpu_should_kick() Sean Christopherson
@ 2026-11-02 15:32 ` Steffen Eiden
2026-11-02 15:34 ` Sean Christopherson
0 siblings, 1 reply; 13+ messages in thread
From: Steffen Eiden @ 2026-11-02 15:32 UTC (permalink / raw)
To: Sean Christopherson
Cc: Marc Zyngier, Oliver Upton, Tianrui Zhao, Bibo Mao, Huacai Chen,
Madhavan Srinivasan, Anup Patel, Paul Walmsley, Palmer Dabbelt,
Albert Ou, Paolo Bonzini, Fuad Tabba, Joey Gouly,
Suzuki K Poulose, Zenghui Yu, Nicholas Piggin, Atish Patra,
Alexandre Ghiti, linux-arm-kernel, kvmarm, kvm, loongarch,
linux-mips, linuxppc-dev, kvm-riscv, linux-riscv, linux-kernel,
Stefan Teodorescu
On Wed, Oct 28, 2026 at 12:02:53PM -0700, Sean Christopherson wrote:
> Drop s390's kvm_arch_vcpu_should_kick() stub as the one and only call site
> is wrapped with "#ifndef CONFIG_S390".
In the somehow near future I'll remove those #ifdefs and use the kick
stuff for kvm_arm64. The native s390 KVM then must at least keep an
(unused) symbol at hand. It seems that the compiler could not optimize
those calls away. So let's keep it there so I do not have to re-add it
soon.
Steffen
>
> No functional change intended.
>
> Signed-off-by: Sean Christopherson <seanjc@google.com>
> ---
> arch/s390/kvm/s390/s390.c | 7 -------
> 1 file changed, 7 deletions(-)
>
> diff --git a/arch/s390/kvm/s390/s390.c b/arch/s390/kvm/s390/s390.c
> index 18fb200f854a..9900a1a1c148 100644
> --- a/arch/s390/kvm/s390/s390.c
> +++ b/arch/s390/kvm/s390/s390.c
> @@ -3922,13 +3922,6 @@ bool kvm_arch_no_poll(struct kvm_vcpu *vcpu)
> return false;
> }
>
> -int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu)
> -{
> - /* kvm common code refers to this, but never calls it */
> - BUG();
> - return 0;
> -}
> -
> static int kvm_arch_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu,
> struct kvm_one_reg *reg)
> {
> --
> 2.56.0.313.g2479322e68-goog
>
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [PATCH 1/7] KVM: s390: Drop unused and unreachable kvm_arch_vcpu_should_kick()
2026-11-02 15:32 ` Steffen Eiden
@ 2026-11-02 15:34 ` Sean Christopherson
0 siblings, 0 replies; 13+ messages in thread
From: Sean Christopherson @ 2026-11-02 15:34 UTC (permalink / raw)
To: Steffen Eiden
Cc: Marc Zyngier, Oliver Upton, Tianrui Zhao, Bibo Mao, Huacai Chen,
Madhavan Srinivasan, Anup Patel, Paul Walmsley, Palmer Dabbelt,
Albert Ou, Paolo Bonzini, Fuad Tabba, Joey Gouly,
Suzuki K Poulose, Zenghui Yu, Nicholas Piggin, Atish Patra,
Alexandre Ghiti, linux-arm-kernel, kvmarm, kvm, loongarch,
linux-mips, linuxppc-dev, kvm-riscv, linux-riscv, linux-kernel,
Stefan Teodorescu
On Mon, Nov 02, 2026, Steffen Eiden wrote:
> On Wed, Oct 28, 2026 at 12:02:53PM -0700, Sean Christopherson wrote:
> > Drop s390's kvm_arch_vcpu_should_kick() stub as the one and only call site
> > is wrapped with "#ifndef CONFIG_S390".
>
> In the somehow near future I'll remove those #ifdefs and use the kick
> stuff for kvm_arm64. The native s390 KVM then must at least keep an
> (unused) symbol at hand. It seems that the compiler could not optimize
> those calls away. So let's keep it there so I do not have to re-add it
> soon.
Please read the rest of the series. kvm_arch_vcpu_should_kick() goes away
entirely.
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 2/7] KVM: Add a @force param to __kvm_vcpu_kick() for PPC backwards compatibility
2026-10-28 19:02 [PATCH 0/7] KVM: Ensure WAIT requests actually wait Sean Christopherson
2026-10-28 19:02 ` [PATCH 1/7] KVM: s390: Drop unused and unreachable kvm_arch_vcpu_should_kick() Sean Christopherson
@ 2026-10-28 19:02 ` Sean Christopherson
2026-10-28 19:02 ` [PATCH 3/7] KVM: PPC: Explicitly force IPIs when directly kicking vCPUs Sean Christopherson
` (4 subsequent siblings)
6 siblings, 0 replies; 13+ messages in thread
From: Sean Christopherson @ 2026-10-28 19:02 UTC (permalink / raw)
To: Marc Zyngier, Oliver Upton, Tianrui Zhao, Bibo Mao, Huacai Chen,
Madhavan Srinivasan, Anup Patel, Paul Walmsley, Palmer Dabbelt,
Albert Ou, Sean Christopherson, Paolo Bonzini
Cc: Fuad Tabba, Joey Gouly, Steffen Eiden, Suzuki K Poulose,
Zenghui Yu, Nicholas Piggin, Atish Patra, Alexandre Ghiti,
linux-arm-kernel, kvmarm, kvm, loongarch, linux-mips,
linuxppc-dev, kvm-riscv, linux-riscv, linux-kernel,
Stefan Teodorescu
Plumb in a @force param to __kvm_vcpu_kick() to force an IPI without
checking kvm_arch_vcpu_should_kick(). The param will be used to drop
kvm_arch_vcpu_should_kick() in favor of kvm_request_needs_ipi() without
regressing PPC, which for unknown reasons unconditionally blasts an IPI
in a variety of kvm_vcpu_kick() flows.
No functional change intended (nothing yet passes in @force=true).
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
include/linux/kvm_host.h | 6 +++---
virt/kvm/kvm_main.c | 10 +++++++---
2 files changed, 10 insertions(+), 6 deletions(-)
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index e7fc94e2910a..3b9844c3906d 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -1570,11 +1570,11 @@ void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu);
bool kvm_vcpu_wake_up(struct kvm_vcpu *vcpu);
#ifndef CONFIG_S390
-void __kvm_vcpu_kick(struct kvm_vcpu *vcpu, bool wait);
+void __kvm_vcpu_kick(struct kvm_vcpu *vcpu, bool wait, bool force);
static inline void kvm_vcpu_kick(struct kvm_vcpu *vcpu)
{
- __kvm_vcpu_kick(vcpu, false);
+ __kvm_vcpu_kick(vcpu, false, false);
}
#endif
@@ -2315,7 +2315,7 @@ static __always_inline void kvm_make_request(int req, struct kvm_vcpu *vcpu)
static inline void kvm_make_request_and_kick(int req, struct kvm_vcpu *vcpu)
{
kvm_make_request(req, vcpu);
- __kvm_vcpu_kick(vcpu, req & KVM_REQUEST_WAIT);
+ __kvm_vcpu_kick(vcpu, req & KVM_REQUEST_WAIT, false);
}
#endif
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index cf4cb586f140..67addb9e48a7 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -3908,7 +3908,7 @@ EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_vcpu_wake_up);
/*
* Kick a sleeping VCPU, or a guest VCPU in guest mode, into host kernel mode.
*/
-void __kvm_vcpu_kick(struct kvm_vcpu *vcpu, bool wait)
+void __kvm_vcpu_kick(struct kvm_vcpu *vcpu, bool wait, bool force)
{
int me, cpu;
@@ -3933,9 +3933,13 @@ void __kvm_vcpu_kick(struct kvm_vcpu *vcpu, bool wait)
* after kvm_arch_vcpu_should_kick(), which could result in sending an
* IPI to the previous pCPU. But, that's ok because the purpose of the
* IPI is to force the vCPU to leave IN_GUEST_MODE, and migrating the
- * vCPU also requires it to leave IN_GUEST_MODE.
+ * vCPU also requires it to leave IN_GUEST_MODE
+ *
+ * Note #2, do NOT check if an IPI is needed if @force is true, as the
+ * check also modifies vcpu->mode and KVM PPC needs to avoid that side
+ * effect for unknown historical reasons.
*/
- if (kvm_arch_vcpu_should_kick(vcpu)) {
+ if (force || kvm_arch_vcpu_should_kick(vcpu)) {
cpu = READ_ONCE(vcpu->cpu);
if (cpu != me && (unsigned int)cpu < nr_cpu_ids && cpu_online(cpu)) {
/*
--
2.56.0.313.g2479322e68-goog
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH 3/7] KVM: PPC: Explicitly force IPIs when directly kicking vCPUs
2026-10-28 19:02 [PATCH 0/7] KVM: Ensure WAIT requests actually wait Sean Christopherson
2026-10-28 19:02 ` [PATCH 1/7] KVM: s390: Drop unused and unreachable kvm_arch_vcpu_should_kick() Sean Christopherson
2026-10-28 19:02 ` [PATCH 2/7] KVM: Add a @force param to __kvm_vcpu_kick() for PPC backwards compatibility Sean Christopherson
@ 2026-10-28 19:02 ` Sean Christopherson
2026-10-30 14:48 ` Gautam Menghani
2026-10-28 19:02 ` [PATCH 4/7] KVM: MIPS: Rework kvm_arch_vcpu_should_kick() to use standard implementation Sean Christopherson
` (3 subsequent siblings)
6 siblings, 1 reply; 13+ messages in thread
From: Sean Christopherson @ 2026-10-28 19:02 UTC (permalink / raw)
To: Marc Zyngier, Oliver Upton, Tianrui Zhao, Bibo Mao, Huacai Chen,
Madhavan Srinivasan, Anup Patel, Paul Walmsley, Palmer Dabbelt,
Albert Ou, Sean Christopherson, Paolo Bonzini
Cc: Fuad Tabba, Joey Gouly, Steffen Eiden, Suzuki K Poulose,
Zenghui Yu, Nicholas Piggin, Atish Patra, Alexandre Ghiti,
linux-arm-kernel, kvmarm, kvm, loongarch, linux-mips,
linuxppc-dev, kvm-riscv, linux-riscv, linux-kernel,
Stefan Teodorescu
Explicitly force an IPI when invoking kvm_vcpu_kick() directly instead of
relying on kvm_arch_vcpu_should_kick() to unconditionally return 1/true.
This will allow dropping kvm_arch_vcpu_should_kick() in favor of
kvm_request_needs_ipi().
No functional change intended (1 || 1 == true).
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
arch/powerpc/include/asm/kvm_ppc.h | 13 ++++++++++++-
arch/powerpc/kvm/book3s.c | 4 ++--
arch/powerpc/kvm/book3s_pr.c | 2 +-
arch/powerpc/kvm/booke.c | 6 +++---
arch/powerpc/kvm/e500_emulate.c | 2 +-
arch/powerpc/kvm/powerpc.c | 2 +-
6 files changed, 20 insertions(+), 9 deletions(-)
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
index 169ea6a7fbad..bbe7378ad0ef 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -30,6 +30,17 @@
#endif
#include <asm/inst.h>
+/*
+ * TODO: For unknown reasons, KVM PPC has historically ignored vcpu->mode when
+ * determining if kicking a vCPU needs an IPI. Either document why that
+ * behavior is necessary, or drop this helper and the @force param from
+ * __kvm_vcpu_kick().
+ */
+static inline void kvmppc_vcpu_kick(struct kvm_vcpu *vcpu)
+{
+ __kvm_vcpu_kick(vcpu, false, true);
+}
+
/*
* KVMPPC_INST_SW_BREAKPOINT is debug Instruction
* for supporting software breakpoint.
@@ -598,7 +609,7 @@ static inline void kvmppc_clear_host_ipi(int cpu)
static inline void kvmppc_fast_vcpu_kick(struct kvm_vcpu *vcpu)
{
- kvm_vcpu_kick(vcpu);
+ kvmppc_vcpu_kick(vcpu);
}
static inline bool kvm_hv_mode_active(void) { return false; }
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
index 2efbe05caed7..dce53c5a3868 100644
--- a/arch/powerpc/kvm/book3s.c
+++ b/arch/powerpc/kvm/book3s.c
@@ -260,7 +260,7 @@ void kvmppc_core_queue_external(struct kvm_vcpu *vcpu,
* external interrupts for the guest just before entering
* the guest. That is OK even if userspace did do a
* KVM_INTERRUPT_SET on a pseries guest vcpu, because the
- * caller (kvm_vcpu_ioctl_interrupt) does a kvm_vcpu_kick()
+ * caller (kvm_vcpu_ioctl_interrupt) does a kvmppc_vcpu_kick()
* which ends up doing a smp_send_reschedule(), which will
* pull the guest all the way out to the host, meaning that
* we will call kvmppc_core_prepare_to_enter() before entering
@@ -827,7 +827,7 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
void kvmppc_decrementer_func(struct kvm_vcpu *vcpu)
{
kvmppc_core_queue_dec(vcpu);
- kvm_vcpu_kick(vcpu);
+ kvmppc_vcpu_kick(vcpu);
}
int kvmppc_core_vcpu_create(struct kvm_vcpu *vcpu)
diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c
index ecfb88bf6464..1894968f2c25 100644
--- a/arch/powerpc/kvm/book3s_pr.c
+++ b/arch/powerpc/kvm/book3s_pr.c
@@ -2066,7 +2066,7 @@ static struct kvmppc_ops kvm_ops_pr = {
.emulate_op = kvmppc_core_emulate_op_pr,
.emulate_mtspr = kvmppc_core_emulate_mtspr_pr,
.emulate_mfspr = kvmppc_core_emulate_mfspr_pr,
- .fast_vcpu_kick = kvm_vcpu_kick,
+ .fast_vcpu_kick = kvmppc_vcpu_kick,
.arch_vm_ioctl = kvm_arch_vm_ioctl_pr,
#ifdef CONFIG_PPC_BOOK3S_64
.hcall_implemented = kvmppc_hcall_impl_pr,
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index 13ad4cf5fa71..fd7f24a68b31 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -650,7 +650,7 @@ static void kvmppc_watchdog_func(struct timer_list *t)
if (new_tsr & TSR_WIS) {
smp_wmb();
kvm_make_request(KVM_REQ_PENDING_TIMER, vcpu);
- kvm_vcpu_kick(vcpu);
+ kvmppc_vcpu_kick(vcpu);
}
/*
@@ -661,7 +661,7 @@ static void kvmppc_watchdog_func(struct timer_list *t)
vcpu->arch.watchdog_enabled) {
smp_wmb();
kvm_make_request(KVM_REQ_WATCHDOG, vcpu);
- kvm_vcpu_kick(vcpu);
+ kvmppc_vcpu_kick(vcpu);
}
/*
@@ -1872,7 +1872,7 @@ void kvmppc_set_tsr_bits(struct kvm_vcpu *vcpu, u32 tsr_bits)
set_bits(tsr_bits, &vcpu->arch.tsr);
smp_wmb();
kvm_make_request(KVM_REQ_PENDING_TIMER, vcpu);
- kvm_vcpu_kick(vcpu);
+ kvmppc_vcpu_kick(vcpu);
}
void kvmppc_clr_tsr_bits(struct kvm_vcpu *vcpu, u32 tsr_bits)
diff --git a/arch/powerpc/kvm/e500_emulate.c b/arch/powerpc/kvm/e500_emulate.c
index 051102d50c31..10cd6b4ab456 100644
--- a/arch/powerpc/kvm/e500_emulate.c
+++ b/arch/powerpc/kvm/e500_emulate.c
@@ -75,7 +75,7 @@ static int kvmppc_e500_emul_msgsnd(struct kvm_vcpu *vcpu, int rb)
int cpir = cvcpu->arch.shared->pir;
if ((param & PPC_DBELL_MSG_BRDCAST) || (cpir == pir)) {
set_bit(prio, &cvcpu->arch.pending_exceptions);
- kvm_vcpu_kick(cvcpu);
+ kvmppc_vcpu_kick(cvcpu);
}
}
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 9194cf492d1c..09c94b849185 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -1903,7 +1903,7 @@ int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt *irq)
kvmppc_core_queue_external(vcpu, irq);
- kvm_vcpu_kick(vcpu);
+ kvmppc_vcpu_kick(vcpu);
return 0;
}
--
2.56.0.313.g2479322e68-goog
^ permalink raw reply related [flat|nested] 13+ messages in thread* Re: [PATCH 3/7] KVM: PPC: Explicitly force IPIs when directly kicking vCPUs
2026-10-28 19:02 ` [PATCH 3/7] KVM: PPC: Explicitly force IPIs when directly kicking vCPUs Sean Christopherson
@ 2026-10-30 14:48 ` Gautam Menghani
2026-10-30 18:57 ` Sean Christopherson
0 siblings, 1 reply; 13+ messages in thread
From: Gautam Menghani @ 2026-10-30 14:48 UTC (permalink / raw)
To: Sean Christopherson
Cc: Marc Zyngier, Oliver Upton, Tianrui Zhao, Bibo Mao, Huacai Chen,
Madhavan Srinivasan, Anup Patel, Paul Walmsley, Palmer Dabbelt,
Albert Ou, Paolo Bonzini, Fuad Tabba, Joey Gouly, Steffen Eiden,
Suzuki K Poulose, Zenghui Yu, Nicholas Piggin, Atish Patra,
Alexandre Ghiti, linux-arm-kernel, kvmarm, kvm, loongarch,
linux-mips, linuxppc-dev, kvm-riscv, linux-riscv, linux-kernel,
Stefan Teodorescu
On Wed, Oct 28, 2026 at 12:02:55PM -0700, Sean Christopherson wrote:
> Explicitly force an IPI when invoking kvm_vcpu_kick() directly instead of
> relying on kvm_arch_vcpu_should_kick() to unconditionally return 1/true.
> This will allow dropping kvm_arch_vcpu_should_kick() in favor of
> kvm_request_needs_ipi().
>
> No functional change intended (1 || 1 == true).
>
> Signed-off-by: Sean Christopherson <seanjc@google.com>
> ---
> arch/powerpc/include/asm/kvm_ppc.h | 13 ++++++++++++-
> arch/powerpc/kvm/book3s.c | 4 ++--
> arch/powerpc/kvm/book3s_pr.c | 2 +-
> arch/powerpc/kvm/booke.c | 6 +++---
> arch/powerpc/kvm/e500_emulate.c | 2 +-
> arch/powerpc/kvm/powerpc.c | 2 +-
> 6 files changed, 20 insertions(+), 9 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
> index 169ea6a7fbad..bbe7378ad0ef 100644
> --- a/arch/powerpc/include/asm/kvm_ppc.h
> +++ b/arch/powerpc/include/asm/kvm_ppc.h
> @@ -30,6 +30,17 @@
> #endif
> #include <asm/inst.h>
>
> +/*
> + * TODO: For unknown reasons, KVM PPC has historically ignored vcpu->mode when
> + * determining if kicking a vCPU needs an IPI. Either document why that
> + * behavior is necessary, or drop this helper and the @force param from
> + * __kvm_vcpu_kick().
> + */
> +static inline void kvmppc_vcpu_kick(struct kvm_vcpu *vcpu)
> +{
> + __kvm_vcpu_kick(vcpu, false, true);
> +}
> +
AFAICS, there is no reason for PPC to always return 1. I was looking at
the old patches on mailing list and found this - https://lore.kernel.org/kvm/0FEE585F-5E21-47F2-A3F0-AD0DE05EBB43@suse.de
```
How about we return 1 for kvm_arch_vcpu_in_guest_mode() on !x86 always, just like it's done today basically? Then we can
worry about needless IPIs later and don't regress from the respective current kick implementations.
```
However, I'll do some testing and get back by mid next week to make sure
there are no suprises.
Thanks,
Gautam
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [PATCH 3/7] KVM: PPC: Explicitly force IPIs when directly kicking vCPUs
2026-10-30 14:48 ` Gautam Menghani
@ 2026-10-30 18:57 ` Sean Christopherson
2026-11-02 14:38 ` Gautam Menghani
0 siblings, 1 reply; 13+ messages in thread
From: Sean Christopherson @ 2026-10-30 18:57 UTC (permalink / raw)
To: Gautam Menghani
Cc: Marc Zyngier, Oliver Upton, Tianrui Zhao, Bibo Mao, Huacai Chen,
Madhavan Srinivasan, Anup Patel, Paul Walmsley, Palmer Dabbelt,
Albert Ou, Paolo Bonzini, Fuad Tabba, Joey Gouly, Steffen Eiden,
Suzuki K Poulose, Zenghui Yu, Nicholas Piggin, Atish Patra,
Alexandre Ghiti, linux-arm-kernel, kvmarm, kvm, loongarch,
linux-mips, linuxppc-dev, kvm-riscv, linux-riscv, linux-kernel,
Stefan Teodorescu
On Fri, Oct 30, 2026, Gautam Menghani wrote:
> On Wed, Oct 28, 2026 at 12:02:55PM -0700, Sean Christopherson wrote:
> > Explicitly force an IPI when invoking kvm_vcpu_kick() directly instead of
> > relying on kvm_arch_vcpu_should_kick() to unconditionally return 1/true.
> > This will allow dropping kvm_arch_vcpu_should_kick() in favor of
> > kvm_request_needs_ipi().
> >
> > No functional change intended (1 || 1 == true).
> >
> > Signed-off-by: Sean Christopherson <seanjc@google.com>
> > ---
> > arch/powerpc/include/asm/kvm_ppc.h | 13 ++++++++++++-
> > arch/powerpc/kvm/book3s.c | 4 ++--
> > arch/powerpc/kvm/book3s_pr.c | 2 +-
> > arch/powerpc/kvm/booke.c | 6 +++---
> > arch/powerpc/kvm/e500_emulate.c | 2 +-
> > arch/powerpc/kvm/powerpc.c | 2 +-
> > 6 files changed, 20 insertions(+), 9 deletions(-)
> >
> > diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
> > index 169ea6a7fbad..bbe7378ad0ef 100644
> > --- a/arch/powerpc/include/asm/kvm_ppc.h
> > +++ b/arch/powerpc/include/asm/kvm_ppc.h
> > @@ -30,6 +30,17 @@
> > #endif
> > #include <asm/inst.h>
> >
> > +/*
> > + * TODO: For unknown reasons, KVM PPC has historically ignored vcpu->mode when
> > + * determining if kicking a vCPU needs an IPI. Either document why that
> > + * behavior is necessary, or drop this helper and the @force param from
> > + * __kvm_vcpu_kick().
> > + */
> > +static inline void kvmppc_vcpu_kick(struct kvm_vcpu *vcpu)
> > +{
> > + __kvm_vcpu_kick(vcpu, false, true);
> > +}
> > +
>
> AFAICS, there is no reason for PPC to always return 1. I was looking at
> the old patches on mailing list and found this - https://lore.kernel.org/kvm/0FEE585F-5E21-47F2-A3F0-AD0DE05EBB43@suse.de
>
> ```
> How about we return 1 for kvm_arch_vcpu_in_guest_mode() on !x86 always, just
> like it's done today basically? Then we can worry about needless IPIs later
> and don't regress from the respective current kick implementations.
> ```
FWIW, I found that as well, but there are a metric ton of kvm_vcpu_kick() calls
that have been added since then, and they scared me.
> However, I'll do some testing and get back by mid next week to make sure
> there are no suprises.
Thanks! If we can drop the PPC behavior, that would be wonderful! Though if
we do that, it should be for 7.5 in a follow-up (this series really should go
into 7.4 due to the SNP issue).
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [PATCH 3/7] KVM: PPC: Explicitly force IPIs when directly kicking vCPUs
2026-10-30 18:57 ` Sean Christopherson
@ 2026-11-02 14:38 ` Gautam Menghani
0 siblings, 0 replies; 13+ messages in thread
From: Gautam Menghani @ 2026-11-02 14:38 UTC (permalink / raw)
To: Sean Christopherson
Cc: Marc Zyngier, Oliver Upton, Tianrui Zhao, Bibo Mao, Huacai Chen,
Madhavan Srinivasan, Anup Patel, Paul Walmsley, Palmer Dabbelt,
Albert Ou, Paolo Bonzini, Fuad Tabba, Joey Gouly, Steffen Eiden,
Suzuki K Poulose, Zenghui Yu, Nicholas Piggin, Atish Patra,
Alexandre Ghiti, linux-arm-kernel, kvmarm, kvm, loongarch,
linux-mips, linuxppc-dev, kvm-riscv, linux-riscv, linux-kernel,
Stefan Teodorescu
On Fri, Oct 30, 2026 at 11:57:10AM -0700, Sean Christopherson wrote:
> On Fri, Oct 30, 2026, Gautam Menghani wrote:
> > On Wed, Oct 28, 2026 at 12:02:55PM -0700, Sean Christopherson wrote:
> > > Explicitly force an IPI when invoking kvm_vcpu_kick() directly instead of
> > > relying on kvm_arch_vcpu_should_kick() to unconditionally return 1/true.
> > > This will allow dropping kvm_arch_vcpu_should_kick() in favor of
> > > kvm_request_needs_ipi().
> > >
> > > No functional change intended (1 || 1 == true).
> > >
> > > Signed-off-by: Sean Christopherson <seanjc@google.com>
> > > ---
> > > arch/powerpc/include/asm/kvm_ppc.h | 13 ++++++++++++-
> > > arch/powerpc/kvm/book3s.c | 4 ++--
> > > arch/powerpc/kvm/book3s_pr.c | 2 +-
> > > arch/powerpc/kvm/booke.c | 6 +++---
> > > arch/powerpc/kvm/e500_emulate.c | 2 +-
> > > arch/powerpc/kvm/powerpc.c | 2 +-
> > > 6 files changed, 20 insertions(+), 9 deletions(-)
> > >
> > > diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
> > > index 169ea6a7fbad..bbe7378ad0ef 100644
> > > --- a/arch/powerpc/include/asm/kvm_ppc.h
> > > +++ b/arch/powerpc/include/asm/kvm_ppc.h
> > > @@ -30,6 +30,17 @@
> > > #endif
> > > #include <asm/inst.h>
> > >
> > > +/*
> > > + * TODO: For unknown reasons, KVM PPC has historically ignored vcpu->mode when
> > > + * determining if kicking a vCPU needs an IPI. Either document why that
> > > + * behavior is necessary, or drop this helper and the @force param from
> > > + * __kvm_vcpu_kick().
> > > + */
> > > +static inline void kvmppc_vcpu_kick(struct kvm_vcpu *vcpu)
> > > +{
> > > + __kvm_vcpu_kick(vcpu, false, true);
> > > +}
> > > +
> >
> > AFAICS, there is no reason for PPC to always return 1. I was looking at
> > the old patches on mailing list and found this - https://lore.kernel.org/kvm/0FEE585F-5E21-47F2-A3F0-AD0DE05EBB43@suse.de
> >
> > ```
> > How about we return 1 for kvm_arch_vcpu_in_guest_mode() on !x86 always, just
> > like it's done today basically? Then we can worry about needless IPIs later
> > and don't regress from the respective current kick implementations.
> > ```
>
> FWIW, I found that as well, but there are a metric ton of kvm_vcpu_kick() calls
> that have been added since then, and they scared me.
>
> > However, I'll do some testing and get back by mid next week to make sure
> > there are no suprises.
>
> Thanks! If we can drop the PPC behavior, that would be wonderful! Though if
> we do that, it should be for 7.5 in a follow-up (this series really should go
> into 7.4 due to the SNP issue).
Yeah I looked into it and realized that the newer variants of KVM on PPC
are not even using vcpu->mode at all. So that has to be fixed from our
end.
For this series,
Reviewed-by: Gautam Menghani <gautam@linux.ibm.com> # PPC
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 4/7] KVM: MIPS: Rework kvm_arch_vcpu_should_kick() to use standard implementation
2026-10-28 19:02 [PATCH 0/7] KVM: Ensure WAIT requests actually wait Sean Christopherson
` (2 preceding siblings ...)
2026-10-28 19:02 ` [PATCH 3/7] KVM: PPC: Explicitly force IPIs when directly kicking vCPUs Sean Christopherson
@ 2026-10-28 19:02 ` Sean Christopherson
2026-10-28 19:02 ` [PATCH 5/7] KVM: Move kvm_arch_vcpu_should_kick() to common code as kvm_vcpu_should_kick() Sean Christopherson
` (2 subsequent siblings)
6 siblings, 0 replies; 13+ messages in thread
From: Sean Christopherson @ 2026-10-28 19:02 UTC (permalink / raw)
To: Marc Zyngier, Oliver Upton, Tianrui Zhao, Bibo Mao, Huacai Chen,
Madhavan Srinivasan, Anup Patel, Paul Walmsley, Palmer Dabbelt,
Albert Ou, Sean Christopherson, Paolo Bonzini
Cc: Fuad Tabba, Joey Gouly, Steffen Eiden, Suzuki K Poulose,
Zenghui Yu, Nicholas Piggin, Atish Patra, Alexandre Ghiti,
linux-arm-kernel, kvmarm, kvm, loongarch, linux-mips,
linuxppc-dev, kvm-riscv, linux-riscv, linux-kernel,
Stefan Teodorescu
Rework MIPS' kvm_arch_vcpu_should_kick() to use the "standard" arch
implementation so that the arch hook can be dropped (MIPS is the only
arch other than PPC that implements a non-standard hook, and PPC uses the
recently added @force param when invoking __kvm_vcpu_kick() instead of
relying on kvm_arch_vcpu_should_kick()).
Convert MIPS to the standard implementation even though the code should be
unreachable (neither kvm_vcpu_kick() nor kvm_make_request_and_kick() are
used by MIPS or common KVM), so that there is a bisection point if the
code is somehow reachable.
No functional change intended (because the code is currently unreachable).
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
arch/mips/kvm/mips.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c
index a53abbba43ea..c37e212bc0a3 100644
--- a/arch/mips/kvm/mips.c
+++ b/arch/mips/kvm/mips.c
@@ -122,7 +122,7 @@ bool kvm_arch_vcpu_in_kernel(struct kvm_vcpu *vcpu)
int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu)
{
- return 1;
+ return kvm_vcpu_exiting_guest_mode(vcpu) == IN_GUEST_MODE;
}
int kvm_arch_enable_virtualization_cpu(void)
--
2.56.0.313.g2479322e68-goog
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH 5/7] KVM: Move kvm_arch_vcpu_should_kick() to common code as kvm_vcpu_should_kick()
2026-10-28 19:02 [PATCH 0/7] KVM: Ensure WAIT requests actually wait Sean Christopherson
` (3 preceding siblings ...)
2026-10-28 19:02 ` [PATCH 4/7] KVM: MIPS: Rework kvm_arch_vcpu_should_kick() to use standard implementation Sean Christopherson
@ 2026-10-28 19:02 ` Sean Christopherson
2026-10-28 19:02 ` [PATCH 6/7] KVM: Plumb the full request into __kvm_vcpu_kick() Sean Christopherson
2026-10-28 19:02 ` [PATCH 7/7] KVM: Drop kvm_vcpu_should_kick() and use kvm_request_needs_ipi() Sean Christopherson
6 siblings, 0 replies; 13+ messages in thread
From: Sean Christopherson @ 2026-10-28 19:02 UTC (permalink / raw)
To: Marc Zyngier, Oliver Upton, Tianrui Zhao, Bibo Mao, Huacai Chen,
Madhavan Srinivasan, Anup Patel, Paul Walmsley, Palmer Dabbelt,
Albert Ou, Sean Christopherson, Paolo Bonzini
Cc: Fuad Tabba, Joey Gouly, Steffen Eiden, Suzuki K Poulose,
Zenghui Yu, Nicholas Piggin, Atish Patra, Alexandre Ghiti,
linux-arm-kernel, kvmarm, kvm, loongarch, linux-mips,
linuxppc-dev, kvm-riscv, linux-riscv, linux-kernel,
Stefan Teodorescu
Dedup kvm_arch_vcpu_should_kick() now that all architectures except for PPC
have identical implementations. PPC's implementation is unreachable as PPC
always invokes __kvm_vcpu_kick() with @force=true.
No functional change intended.
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
arch/arm64/kvm/arm.c | 5 -----
arch/loongarch/kvm/vcpu.c | 5 -----
arch/mips/kvm/mips.c | 5 -----
arch/powerpc/kvm/powerpc.c | 5 -----
arch/riscv/kvm/vcpu.c | 5 -----
arch/x86/kvm/x86.c | 5 -----
include/linux/kvm_host.h | 1 -
virt/kvm/kvm_main.c | 11 ++++++++---
8 files changed, 8 insertions(+), 34 deletions(-)
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 775d11f96813..99d540d67b5b 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -128,11 +128,6 @@ bool is_kvm_arm_initialised(void)
return kvm_arm_initialised;
}
-int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu)
-{
- return kvm_vcpu_exiting_guest_mode(vcpu) == IN_GUEST_MODE;
-}
-
int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
struct kvm_enable_cap *cap)
{
diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c
index 4026b9bf9f2d..76afd386abd2 100644
--- a/arch/loongarch/kvm/vcpu.c
+++ b/arch/loongarch/kvm/vcpu.c
@@ -379,11 +379,6 @@ int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
vcpu->arch.mp_state.mp_state == KVM_MP_STATE_RUNNABLE;
}
-int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu)
-{
- return kvm_vcpu_exiting_guest_mode(vcpu) == IN_GUEST_MODE;
-}
-
bool kvm_arch_vcpu_in_kernel(struct kvm_vcpu *vcpu)
{
unsigned long val;
diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c
index c37e212bc0a3..273dd932d119 100644
--- a/arch/mips/kvm/mips.c
+++ b/arch/mips/kvm/mips.c
@@ -120,11 +120,6 @@ bool kvm_arch_vcpu_in_kernel(struct kvm_vcpu *vcpu)
return false;
}
-int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu)
-{
- return kvm_vcpu_exiting_guest_mode(vcpu) == IN_GUEST_MODE;
-}
-
int kvm_arch_enable_virtualization_cpu(void)
{
return kvm_mips_callbacks->enable_virtualization_cpu();
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 09c94b849185..ac259fcd85c2 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -62,11 +62,6 @@ bool kvm_arch_vcpu_in_kernel(struct kvm_vcpu *vcpu)
return false;
}
-int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu)
-{
- return 1;
-}
-
/*
* Common checks before entering the guest world. Call with interrupts
* enabled.
diff --git a/arch/riscv/kvm/vcpu.c b/arch/riscv/kvm/vcpu.c
index dd786f758eb7..3981ba39ffc2 100644
--- a/arch/riscv/kvm/vcpu.c
+++ b/arch/riscv/kvm/vcpu.c
@@ -239,11 +239,6 @@ int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
!kvm_riscv_vcpu_stopped(vcpu) && !vcpu->arch.pause);
}
-int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu)
-{
- return kvm_vcpu_exiting_guest_mode(vcpu) == IN_GUEST_MODE;
-}
-
bool kvm_arch_vcpu_in_kernel(struct kvm_vcpu *vcpu)
{
return (vcpu->arch.guest_context.sstatus & SR_SPP) ? true : false;
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 32563a91fba9..d9fa2690153a 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -10472,11 +10472,6 @@ unsigned long kvm_arch_vcpu_get_ip(struct kvm_vcpu *vcpu)
return kvm_rip_read(vcpu);
}
-int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu)
-{
- return kvm_vcpu_exiting_guest_mode(vcpu) == IN_GUEST_MODE;
-}
-
static inline u32 kvm_async_pf_hash_fn(gfn_t gfn)
{
BUILD_BUG_ON(!is_power_of_2(ASYNC_PF_PER_VCPU));
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 3b9844c3906d..9db42f58c561 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -1694,7 +1694,6 @@ void kvm_arch_disable_virtualization_cpu(void);
bool kvm_vcpu_has_events(struct kvm_vcpu *vcpu);
int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu);
bool kvm_arch_vcpu_in_kernel(struct kvm_vcpu *vcpu);
-int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu);
bool kvm_arch_dy_runnable(struct kvm_vcpu *vcpu);
bool kvm_arch_dy_has_pending_interrupt(struct kvm_vcpu *vcpu);
bool kvm_arch_vcpu_preempted_in_kernel(struct kvm_vcpu *vcpu);
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 67addb9e48a7..e1a9da8b43d7 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -191,7 +191,7 @@ void vcpu_put(struct kvm_vcpu *vcpu)
}
EXPORT_SYMBOL_FOR_KVM_INTERNAL(vcpu_put);
-/* TODO: merge with kvm_arch_vcpu_should_kick */
+/* TODO: merge with kvm_vcpu_should_kick */
static bool kvm_request_needs_ipi(struct kvm_vcpu *vcpu, unsigned req)
{
int mode = kvm_vcpu_exiting_guest_mode(vcpu);
@@ -209,6 +209,11 @@ static bool kvm_request_needs_ipi(struct kvm_vcpu *vcpu, unsigned req)
return mode == IN_GUEST_MODE;
}
+static int kvm_vcpu_should_kick(struct kvm_vcpu *vcpu)
+{
+ return kvm_vcpu_exiting_guest_mode(vcpu) == IN_GUEST_MODE;
+}
+
static void ack_kick(void *_completed)
{
}
@@ -3930,7 +3935,7 @@ void __kvm_vcpu_kick(struct kvm_vcpu *vcpu, bool wait, bool force)
/*
* Note, the vCPU could get migrated to a different pCPU at any point
- * after kvm_arch_vcpu_should_kick(), which could result in sending an
+ * after kvm_vcpu_should_kick(), which could result in sending an
* IPI to the previous pCPU. But, that's ok because the purpose of the
* IPI is to force the vCPU to leave IN_GUEST_MODE, and migrating the
* vCPU also requires it to leave IN_GUEST_MODE
@@ -3939,7 +3944,7 @@ void __kvm_vcpu_kick(struct kvm_vcpu *vcpu, bool wait, bool force)
* check also modifies vcpu->mode and KVM PPC needs to avoid that side
* effect for unknown historical reasons.
*/
- if (force || kvm_arch_vcpu_should_kick(vcpu)) {
+ if (force || kvm_vcpu_should_kick(vcpu)) {
cpu = READ_ONCE(vcpu->cpu);
if (cpu != me && (unsigned int)cpu < nr_cpu_ids && cpu_online(cpu)) {
/*
--
2.56.0.313.g2479322e68-goog
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH 6/7] KVM: Plumb the full request into __kvm_vcpu_kick()
2026-10-28 19:02 [PATCH 0/7] KVM: Ensure WAIT requests actually wait Sean Christopherson
` (4 preceding siblings ...)
2026-10-28 19:02 ` [PATCH 5/7] KVM: Move kvm_arch_vcpu_should_kick() to common code as kvm_vcpu_should_kick() Sean Christopherson
@ 2026-10-28 19:02 ` Sean Christopherson
2026-10-28 19:02 ` [PATCH 7/7] KVM: Drop kvm_vcpu_should_kick() and use kvm_request_needs_ipi() Sean Christopherson
6 siblings, 0 replies; 13+ messages in thread
From: Sean Christopherson @ 2026-10-28 19:02 UTC (permalink / raw)
To: Marc Zyngier, Oliver Upton, Tianrui Zhao, Bibo Mao, Huacai Chen,
Madhavan Srinivasan, Anup Patel, Paul Walmsley, Palmer Dabbelt,
Albert Ou, Sean Christopherson, Paolo Bonzini
Cc: Fuad Tabba, Joey Gouly, Steffen Eiden, Suzuki K Poulose,
Zenghui Yu, Nicholas Piggin, Atish Patra, Alexandre Ghiti,
linux-arm-kernel, kvmarm, kvm, loongarch, linux-mips,
linuxppc-dev, kvm-riscv, linux-riscv, linux-kernel,
Stefan Teodorescu
Plumb the full request instead of just a "wait" boolean into
__kvm_vcpu_kick() so that it can use kvm_request_needs_ipi() instead of
the flawed kvm_vcpu_should_kick().
No functional change intended.
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
arch/powerpc/include/asm/kvm_ppc.h | 2 +-
include/linux/kvm_host.h | 6 +++---
virt/kvm/kvm_main.c | 17 +++++++++--------
3 files changed, 13 insertions(+), 12 deletions(-)
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
index bbe7378ad0ef..011dc422af78 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -38,7 +38,7 @@
*/
static inline void kvmppc_vcpu_kick(struct kvm_vcpu *vcpu)
{
- __kvm_vcpu_kick(vcpu, false, true);
+ __kvm_vcpu_kick(vcpu, 0, true);
}
/*
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 9db42f58c561..035b1bdd8c09 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -1570,11 +1570,11 @@ void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu);
bool kvm_vcpu_wake_up(struct kvm_vcpu *vcpu);
#ifndef CONFIG_S390
-void __kvm_vcpu_kick(struct kvm_vcpu *vcpu, bool wait, bool force);
+void __kvm_vcpu_kick(struct kvm_vcpu *vcpu, int request, bool force);
static inline void kvm_vcpu_kick(struct kvm_vcpu *vcpu)
{
- __kvm_vcpu_kick(vcpu, false, false);
+ __kvm_vcpu_kick(vcpu, 0, false);
}
#endif
@@ -2314,7 +2314,7 @@ static __always_inline void kvm_make_request(int req, struct kvm_vcpu *vcpu)
static inline void kvm_make_request_and_kick(int req, struct kvm_vcpu *vcpu)
{
kvm_make_request(req, vcpu);
- __kvm_vcpu_kick(vcpu, req & KVM_REQUEST_WAIT, false);
+ __kvm_vcpu_kick(vcpu, req, false);
}
#endif
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index e1a9da8b43d7..f1792256576b 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -3913,7 +3913,7 @@ EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_vcpu_wake_up);
/*
* Kick a sleeping VCPU, or a guest VCPU in guest mode, into host kernel mode.
*/
-void __kvm_vcpu_kick(struct kvm_vcpu *vcpu, bool wait, bool force)
+void __kvm_vcpu_kick(struct kvm_vcpu *vcpu, int req, bool force)
{
int me, cpu;
@@ -3948,14 +3948,15 @@ void __kvm_vcpu_kick(struct kvm_vcpu *vcpu, bool wait, bool force)
cpu = READ_ONCE(vcpu->cpu);
if (cpu != me && (unsigned int)cpu < nr_cpu_ids && cpu_online(cpu)) {
/*
- * Use a reschedule IPI to kick the vCPU if the caller
- * doesn't need to wait for a response, as KVM allows
- * kicking vCPUs while IRQs are disabled, but using the
- * SMP function call framework with IRQs disabled can
- * deadlock due to taking cross-CPU locks.
+ * Use a reschedule IPI to kick the vCPU if the request
+ * doesn't need to wait for a response (or there is no
+ * request), as KVM allows kicking vCPUs while IRQs are
+ * disabled, but using the SMP function call framework
+ * with IRQs disabled can deadlock due to taking cross-
+ * CPU locks.
*/
- if (wait)
- smp_call_function_single(cpu, ack_kick, NULL, wait);
+ if (req & KVM_REQUEST_WAIT)
+ smp_call_function_single(cpu, ack_kick, NULL, true);
else
smp_send_reschedule(cpu);
}
--
2.56.0.313.g2479322e68-goog
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH 7/7] KVM: Drop kvm_vcpu_should_kick() and use kvm_request_needs_ipi()
2026-10-28 19:02 [PATCH 0/7] KVM: Ensure WAIT requests actually wait Sean Christopherson
` (5 preceding siblings ...)
2026-10-28 19:02 ` [PATCH 6/7] KVM: Plumb the full request into __kvm_vcpu_kick() Sean Christopherson
@ 2026-10-28 19:02 ` Sean Christopherson
6 siblings, 0 replies; 13+ messages in thread
From: Sean Christopherson @ 2026-10-28 19:02 UTC (permalink / raw)
To: Marc Zyngier, Oliver Upton, Tianrui Zhao, Bibo Mao, Huacai Chen,
Madhavan Srinivasan, Anup Patel, Paul Walmsley, Palmer Dabbelt,
Albert Ou, Sean Christopherson, Paolo Bonzini
Cc: Fuad Tabba, Joey Gouly, Steffen Eiden, Suzuki K Poulose,
Zenghui Yu, Nicholas Piggin, Atish Patra, Alexandre Ghiti,
linux-arm-kernel, kvmarm, kvm, loongarch, linux-mips,
linuxppc-dev, kvm-riscv, linux-riscv, linux-kernel,
Stefan Teodorescu
Drop kvm_vcpu_should_kick() in favor of kvm_request_needs_ipi() to fix a
bug where KVM will fail to wait for a vCPU to exit guest mode if the vCPU
was already marked as EXITING_GUEST_MODE by a concurrent non-waiting kick.
Because kvm_vcpu_should_kick() (was kvm_arch_vcpu_should_kick()) only waits
(and sends an IPI to do so) if the target vCPU is fully IN_GUEST_MODE, the
sending task will proceed even though it hasn't actually guaranteed the
vCPU as fully exited the guest.
The flaw is most problematic for SNP VMSA invalidation with in-place gmem
conversion, as KVM invokes kvm_gmem_invalidate_start() => rmp_make_shared()
(via kvm_gmem_make_shared() in quick succession when in-place conversion is
enabled. I.e. if the target has been marked as EXITING_GUEST_MODE but has
not yet received the other kicker's IPI, then updating the RMP will fail as
the VMSA is still in-use and subsequent accesses to the page will encounter
unexpected RMP #PFs.
Note, the bug exists and affects VMSA invalidation even without in-place
conversion, but is significantly more difficult to hit as PUNCH_HOLE and
.release() have to wade through a lot more code and several locks to get
from invalidation to kvm_gmem_free_folio().
Note #2, currently only x86 uses kvm_make_request_and_kick(), i.e. this is
a glorified nop for all other architectures as the KVM_REQUEST_WAIT path is
never taken.
Fixes: 309d28576f0a ("KVM: SVM: Fix SNP AP destroy race with VMRUN")
Fixes: d1a3c2162334 ("KVM: SEV: Forcefully invalidate SNP VMSA if its backing gmem page is zapped")
Reported-by: Stefan Teodorescu <fane@google.com>
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
virt/kvm/kvm_main.c | 10 ++--------
1 file changed, 2 insertions(+), 8 deletions(-)
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index f1792256576b..f99a714698e3 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -191,7 +191,6 @@ void vcpu_put(struct kvm_vcpu *vcpu)
}
EXPORT_SYMBOL_FOR_KVM_INTERNAL(vcpu_put);
-/* TODO: merge with kvm_vcpu_should_kick */
static bool kvm_request_needs_ipi(struct kvm_vcpu *vcpu, unsigned req)
{
int mode = kvm_vcpu_exiting_guest_mode(vcpu);
@@ -209,11 +208,6 @@ static bool kvm_request_needs_ipi(struct kvm_vcpu *vcpu, unsigned req)
return mode == IN_GUEST_MODE;
}
-static int kvm_vcpu_should_kick(struct kvm_vcpu *vcpu)
-{
- return kvm_vcpu_exiting_guest_mode(vcpu) == IN_GUEST_MODE;
-}
-
static void ack_kick(void *_completed)
{
}
@@ -3935,7 +3929,7 @@ void __kvm_vcpu_kick(struct kvm_vcpu *vcpu, int req, bool force)
/*
* Note, the vCPU could get migrated to a different pCPU at any point
- * after kvm_vcpu_should_kick(), which could result in sending an
+ * after kvm_request_needs_ipi(), which could result in sending an
* IPI to the previous pCPU. But, that's ok because the purpose of the
* IPI is to force the vCPU to leave IN_GUEST_MODE, and migrating the
* vCPU also requires it to leave IN_GUEST_MODE
@@ -3944,7 +3938,7 @@ void __kvm_vcpu_kick(struct kvm_vcpu *vcpu, int req, bool force)
* check also modifies vcpu->mode and KVM PPC needs to avoid that side
* effect for unknown historical reasons.
*/
- if (force || kvm_vcpu_should_kick(vcpu)) {
+ if (force || kvm_request_needs_ipi(vcpu, req)) {
cpu = READ_ONCE(vcpu->cpu);
if (cpu != me && (unsigned int)cpu < nr_cpu_ids && cpu_online(cpu)) {
/*
--
2.56.0.313.g2479322e68-goog
^ permalink raw reply related [flat|nested] 13+ messages in thread