Skip to content

Commit

Permalink
KVM: PPC: Book 3S: XICS: Fix potential issue with duplicate IRQ resends
Browse files Browse the repository at this point in the history
It is possible that in the following order, one irq is resent twice:

        CPU 1                                   CPU 2

ics_check_resend()
  lock ics_lock
    see resend set
  unlock ics_lock
                                       /* change affinity of the irq */
                                       kvmppc_xics_set_xive()
                                         write_xive()
                                           lock ics_lock
                                             see resend set
                                           unlock ics_lock

                                         icp_deliver_irq() /* resend */

  icp_deliver_irq() /* resend again */

It doesn't have any user-visible effect at present, but needs to be avoided
when the following patch implementing the P/Q stuff is applied.

This patch clears the resend flag before releasing the ics lock, when we
know we will do a re-delivery after checking the flag, or setting the flag.

Signed-off-by: Li Zhong <zhong@linux.vnet.ibm.com>
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
  • Loading branch information
Li Zhong authored and Paul Mackerras committed Jan 26, 2017
1 parent 37451bc commit bf5a71d
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 0 deletions.
3 changes: 3 additions & 0 deletions arch/powerpc/kvm/book3s_hv_rm_xics.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ static void ics_rm_check_resend(struct kvmppc_xics *xics,
if (!state->resend)
continue;

state->resend = 0;

arch_spin_unlock(&ics->lock);
icp_rm_deliver_irq(xics, icp, state->number);
arch_spin_lock(&ics->lock);
Expand Down Expand Up @@ -400,6 +402,7 @@ static void icp_rm_deliver_irq(struct kvmppc_xics *xics, struct kvmppc_icp *icp,
*/
smp_mb();
if (!icp->state.need_resend) {
state->resend = 0;
arch_spin_unlock(&ics->lock);
goto again;
}
Expand Down
4 changes: 4 additions & 0 deletions arch/powerpc/kvm/book3s_xics.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ static void ics_check_resend(struct kvmppc_xics *xics, struct kvmppc_ics *ics,
if (!state->resend)
continue;

state->resend = 0;

XICS_DBG("resend %#x prio %#x\n", state->number,
state->priority);

Expand Down Expand Up @@ -155,6 +157,7 @@ static bool write_xive(struct kvmppc_xics *xics, struct kvmppc_ics *ics,
deliver = false;
if ((state->masked_pending || state->resend) && priority != MASKED) {
state->masked_pending = 0;
state->resend = 0;
deliver = true;
}

Expand Down Expand Up @@ -488,6 +491,7 @@ static void icp_deliver_irq(struct kvmppc_xics *xics, struct kvmppc_icp *icp,
*/
smp_mb();
if (!icp->state.need_resend) {
state->resend = 0;
arch_spin_unlock(&ics->lock);
local_irq_restore(flags);
goto again;
Expand Down

0 comments on commit bf5a71d

Please sign in to comment.