From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757254AbcAMKbI (ORCPT ); Wed, 13 Jan 2016 05:31:08 -0500 Received: from mail1.windriver.com ([147.11.146.13]:35602 "EHLO mail1.windriver.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757210AbcAMKbF (ORCPT ); Wed, 13 Jan 2016 05:31:05 -0500 From: To: , , Subject: [PATCH 1/1] Revert "genirq: Remove the second parameter from handle_irq_event_percpu()" Date: Wed, 13 Jan 2016 18:31:56 +0800 Message-ID: <1452681116-20924-1-git-send-email-zyjzyj2000@gmail.com> X-Mailer: git-send-email 1.7.9.5 MIME-Version: 1.0 Content-Type: text/plain Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Zhu Yanjun After this commit 71f64340fc0e ("genirq: Remove the second parameter from handle_irq_event_percpu()") is applied, the variable action is not protected by raw_spin_lock. The following calltrace will pop up. BUG: unable to handle kernel NULL pointer dereference at 0000000000000008 IP: [] handle_irq_event_percpu+0x31/0x1c0 PGD 0 Oops: 0000 [#1] PREEMPT SMP Modules linked in: CPU: 2 PID: 0 Comm: swapper/2 Not tainted 4.4.0 #30 task: ffff88003d2ed040 ti: ffff88003d380000 task.ti: ffff88003d380000 RIP: 0010:[] [] handle_irq_event_percpu+0x31/0x1c0 RSP: 0018:ffff88003eb03ed8 EFLAGS: 00010046 RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000010003 RDX: 0000000080010003 RSI: 0000000000000000 RDI: ffff88003d02ac00 RBP: ffff88003eb03f10 R08: ffff88003d380000 R09: 0000000000000002 R10: 0000000000027e88 R11: 0000000000000282 R12: 0000000000000004 R13: ffff88003d02ac38 R14: 0000000000000000 R15: 0000000000000000 FS: 0000000000000000(0000) GS:ffff88003eb00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b CR2: 0000000000000008 CR3: 0000000001e0a000 CR4: 00000000000006e0 Stack: ffff88003d02ac00 0000000000000007 ffff88003d02ac00 ffff88003d02acb4 ffff88003d02ac38 0000000000000034 0000000000000000 ffff88003eb03f38 ffffffff810a4b5c ffff88003d02ac00 ffff88003d02acb4 ffff88003d02ac38 Call Trace: [] handle_irq_event+0x3c/0x60 [] handle_edge_irq+0xcf/0x160 [] handle_irq+0x1a/0x30 [] do_IRQ+0x57/0xf0 [] common_interrupt+0x7f/0x7f [] ? _raw_write_unlock_irq+0x12/0x30 [] _raw_spin_unlock_irq+0xe/0x10 [] finish_task_switch+0x9a/0x1f0 [] __schedule+0x3c5/0xb60 [] schedule+0x3f/0x90 [] schedule_preempt_disabled+0x18/0x30 [] cpu_startup_entry+0x13c/0x320 [] start_secondary+0xf1/0x100 RIP [] handle_irq_event_percpu+0x31/0x1c0 RSP CR2: 0000000000000008 ---[ end trace c62dc8f0b2aee0f5 ]--- Kernel panic - not syncing: Fatal exception in interrupt Kernel Offset: disabled ---[ end Kernel panic - not syncing: Fatal exception in interrupt Signed-off-by: Zhu Yanjun --- kernel/irq/chip.c | 2 +- kernel/irq/handle.c | 7 ++++--- kernel/irq/internals.h | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index 5797909..ce483ac 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -692,7 +692,7 @@ void handle_percpu_irq(struct irq_desc *desc) if (chip->irq_ack) chip->irq_ack(&desc->irq_data); - handle_irq_event_percpu(desc); + handle_irq_event_percpu(desc, desc->action); if (chip->irq_eoi) chip->irq_eoi(&desc->irq_data); diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c index a302cf9..e25a83b 100644 --- a/kernel/irq/handle.c +++ b/kernel/irq/handle.c @@ -132,11 +132,11 @@ void __irq_wake_thread(struct irq_desc *desc, struct irqaction *action) wake_up_process(action->thread); } -irqreturn_t handle_irq_event_percpu(struct irq_desc *desc) +irqreturn_t +handle_irq_event_percpu(struct irq_desc *desc, struct irqaction *action) { irqreturn_t retval = IRQ_NONE; unsigned int flags = 0, irq = desc->irq_data.irq; - struct irqaction *action = desc->action; do { irqreturn_t res; @@ -184,13 +184,14 @@ irqreturn_t handle_irq_event_percpu(struct irq_desc *desc) irqreturn_t handle_irq_event(struct irq_desc *desc) { + struct irqaction *action = desc->action; irqreturn_t ret; desc->istate &= ~IRQS_PENDING; irqd_set(&desc->irq_data, IRQD_IRQ_INPROGRESS); raw_spin_unlock(&desc->lock); - ret = handle_irq_event_percpu(desc); + ret = handle_irq_event_percpu(desc, action); raw_spin_lock(&desc->lock); irqd_clear(&desc->irq_data, IRQD_IRQ_INPROGRESS); diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h index fcab63c..25a2c9c 100644 --- a/kernel/irq/internals.h +++ b/kernel/irq/internals.h @@ -83,7 +83,7 @@ extern void irq_mark_irq(unsigned int irq); extern void init_kstat_irqs(struct irq_desc *desc, int node, int nr); -irqreturn_t handle_irq_event_percpu(struct irq_desc *desc); +irqreturn_t handle_irq_event_percpu(struct irq_desc *desc, struct irqaction *action); irqreturn_t handle_irq_event(struct irq_desc *desc); /* Resending of interrupts :*/ -- 1.9.1