From 02908f7424ee74dbfc3776fd8a45ebcafa0f0ff7 Mon Sep 17 00:00:00 2001 From: Thomas Tai Date: Mon, 10 Jul 2017 10:55:55 -0600 Subject: [PATCH] sparc64: fix vio handshake issue When rebooting multiple LDoms together with bind/unbind a separate LDom, kernel panic with vio handshake error. The panic is caused by vio trying to allocate a buffer which is not freed properly. The ldc_unbind should unconfigure and stop the ldc queue before freeing the irq. If the irq is freed before stopping the queue, interrupts can continue to happen after the irq is freed which may cause issue. Orabug: 26259622 Signed-off-by: Thomas Tai Signed-off-by: Allen Pais Reviewed-by: Shannon Nelson --- arch/sparc/kernel/ldc.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/arch/sparc/kernel/ldc.c b/arch/sparc/kernel/ldc.c index 87be2d13532c..10fdbe63bc89 100644 --- a/arch/sparc/kernel/ldc.c +++ b/arch/sparc/kernel/ldc.c @@ -1319,12 +1319,6 @@ EXPORT_SYMBOL(ldc_alloc); void ldc_unbind(struct ldc_channel *lp) { - if (lp->flags & LDC_FLAG_REGISTERED_IRQS) { - free_irq(lp->cfg.rx_irq, lp); - free_irq(lp->cfg.tx_irq, lp); - lp->flags &= ~LDC_FLAG_REGISTERED_IRQS; - } - if (lp->flags & LDC_FLAG_REGISTERED_QUEUES) { sun4v_ldc_tx_qconf(lp->id, 0, 0); sun4v_ldc_rx_qconf(lp->id, 0, 0); @@ -1335,6 +1329,11 @@ void ldc_unbind(struct ldc_channel *lp) free_queue(lp->rx_num_entries, lp->rx_base); lp->flags &= ~LDC_FLAG_ALLOCED_QUEUES; } + if (lp->flags & LDC_FLAG_REGISTERED_IRQS) { + free_irq(lp->cfg.rx_irq, lp); + free_irq(lp->cfg.tx_irq, lp); + lp->flags &= ~LDC_FLAG_REGISTERED_IRQS; + } ldc_set_state(lp, LDC_STATE_INIT); } -- 2.50.1