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 arbitary interrupt to the guest and was causing guest to hang up while running these selftests. Signed-off-by: Ritesh Harjani (IBM) <[email protected]> --- arch/powerpc/kvm/book3s.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index 2efbe05caed7..e4152e9a0d96 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -401,17 +401,19 @@ 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); - while (priority < BOOK3S_IRQPRIO_MAX) { - if (kvmppc_book3s_irqprio_deliver(vcpu, priority) && - clear_irqprio(vcpu, priority)) { - clear_bit(priority, &vcpu->arch.pending_exceptions); - break; - } + if (*pending) { + priority = __ffs(*pending); + while (priority < BOOK3S_IRQPRIO_MAX) { + if (kvmppc_book3s_irqprio_deliver(vcpu, priority) && + clear_irqprio(vcpu, priority)) { + clear_bit(priority, &vcpu->arch.pending_exceptions); + break; + } - priority = find_next_bit(pending, - BITS_PER_BYTE * sizeof(*pending), - priority + 1); + priority = find_next_bit(pending, + BITS_PER_BYTE * sizeof(*pending), + priority + 1); + } } /* Tell the guest about our interrupt status */ -- 2.39.5
