powerpc/kvm/xive: Don't use existing "prodded" flag for xive escalations
Subsystems (3)
PATCH 1/1 powerpc/kvm/xive: Don't use existing "prodded" flag for xive escalations
The prodded flag is only cleared at the beginning of H_CEDE, so every time we have an escalation, we will cause the *next* H_CEDE to return immediately.
Instead use a dedicated "irq_pending" flag to indicate that a guest interrupt is pending for the VCPU. We don't reuse the existing exception bitmap as to avoid expensive atomic ops.
Signed-off-by Benjamin Herrenschmidt <[email protected]>
--- arch/powerpc/include/asm/kvm_host.h | 1 + arch/powerpc/kernel/asm-offsets.c | 1 + arch/powerpc/kvm/book3s_hv.c | 2 +- arch/powerpc/kvm/book3s_hv_rmhandlers.S | 10 ++++++++++ arch/powerpc/kvm/book3s_xive.c | 3 +-- 5 files changed, 14 insertions(+), 3 deletions(-)
arch/powerpc/include/asm/kvm_host.h +1 -0
@@ -711,6 +711,7 @@ struct kvm_vcpu_arch {u8 ceded;u8 prodded;u8 doorbell_request; +u8 irq_pending;/* Used by XIVE to signal pending guest irqs */ u32 last_inst;struct swait_queue_head *wqp;
arch/powerpc/kernel/asm-offsets.c +1 -0
@@ -514,6 +514,7 @@ int main(void)OFFSET (VCPU_PENDING_EXC , kvm_vcpu, arch.pending_exceptions);OFFSET (VCPU_CEDED , kvm_vcpu, arch.ceded);OFFSET (VCPU_PRODDED , kvm_vcpu, arch.prodded); +OFFSET (VCPU_IRQ_PENDING , kvm_vcpu, arch.irq_pending);OFFSET (VCPU_DBELL_REQ , kvm_vcpu, arch.doorbell_request);OFFSET (VCPU_MMCR , kvm_vcpu, arch.mmcr);OFFSET (VCPU_PMC , kvm_vcpu, arch.pmc);
arch/powerpc/kvm/book3s_hv.c +1 -1
@@ -2942,7 +2942,7 @@ static inline bool xive_interrupt_pending(struct kvm_vcpu *vcpu) {if (!xive_enabled ())return false; -return vcpu->arch.xive_saved_state.pipr < +return vcpu->arch.irq_pending || vcpu->arch.xive_saved_state.pipr < vcpu->arch.xive_saved_state.cppr; }#else
arch/powerpc/kvm/book3s_hv_rmhandlers.S +10 -0
@@ -997,6 +997,16 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_300) li r9, 1 stw r9, VCPU_XIVE_PUSHED(r4) eieio + + /* + * We clear the irq_pending flag. There is a small chance of a + * race vs. the escalation interrupt happening on another + * processor setting it again, but the only consequence is to + * cause a spurrious wakeup on the next H_CEDE which is not an + * issue. + */ + li r0,0 + stb r0, VCPU_IRQ_PENDING(r4); no_xive: #endif /* CONFIG_KVM_XICS */
arch/powerpc/kvm/book3s_xive.c +1 -2
@@ -84,8 +84,7 @@ static irqreturn_t xive_esc_irq(int irq, void *data) {struct kvm_vcpu *vcpu = data; -/* We use the existing H_PROD mechanism to wake up the target */ - vcpu->arch.prodded =1 ; + vcpu->arch.irq_pending =1 ;smp_mb ();if (vcpu->arch.ceded)kvmppc_fast_vcpu_kick (vcpu);