From patchwork Tue Oct 9 05:54:19 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Len Brown X-Patchwork-Id: 1568251 Return-Path: X-Original-To: patchwork-linux-acpi@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id E79B93FE80 for ; Tue, 9 Oct 2012 06:04:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753010Ab2JIGEF (ORCPT ); Tue, 9 Oct 2012 02:04:05 -0400 Received: from mail-qc0-f174.google.com ([209.85.216.174]:34159 "EHLO mail-qc0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752967Ab2JIGD5 (ORCPT ); Tue, 9 Oct 2012 02:03:57 -0400 Received: by mail-qc0-f174.google.com with SMTP id d3so3587985qch.19 for ; Mon, 08 Oct 2012 23:03:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references:in-reply-to:references:reply-to:organization; bh=Xx2lDRz3ogYdkKYWrwnj/jNXXsOth25RfhxTmPTzOWY=; b=c2FcB8necpMIarzGmI+Y8rsrzttSNWA0iJYu0qM28btIy6FEgeCTI3EwiwK/uZpIYR uj+fciS41vtJPvRKkQBOZ+8mPNJuJ9jXW+7V/567yQP9NGl4Z7cAOBUzxTFqyWr1NM+L XzYT4sFo+erOKcwzos/23iMYnVEUZGJHOzu9/Rr05F//A1YarY/BG/ytp1ySRzDxN+UY I1tEMmrcaTHlGfCh14u5SCrD340MIaCNbsZ2prNoc+VdVWSY6m2nnmWO3S8X2tFofWTY fNAq4ixsGJJBJ02MQsVLRbZHgDV/3/b+HibnmTaYZzIFcUNYrKaWONZcAV8MT/FbrH3S vCzA== Received: by 10.224.206.198 with SMTP id fv6mr33221939qab.65.1349762637290; Mon, 08 Oct 2012 23:03:57 -0700 (PDT) Received: from x980.localdomain6 (pool-74-104-146-186.bstnma.fios.verizon.net. [74.104.146.186]) by mx.google.com with ESMTPS id ck11sm20206037qab.17.2012.10.08.23.03.55 (version=SSLv3 cipher=OTHER); Mon, 08 Oct 2012 23:03:56 -0700 (PDT) From: Len Brown To: linux-acpi@vger.kernel.org, linux-pm@vger.kernel.org Cc: linux-kernel@vger.kernel.org, "Srivatsa S. Bhat" , Len Brown Subject: [PATCH 29/30] ACPI idle, CPU hotplug: Fix NULL pointer dereference during hotplug Date: Tue, 9 Oct 2012 01:54:19 -0400 Message-Id: X-Mailer: git-send-email 1.8.0.rc1 In-Reply-To: <1349762060-25334-1-git-send-email-lenb@kernel.org> References: <1349762060-25334-1-git-send-email-lenb@kernel.org> In-Reply-To: References: Reply-To: Len Brown Organization: Intel Open Source Technology Center Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org From: "Srivatsa S. Bhat" On a KVM guest, when a CPU is taken offline and brought back online, we hit the following NULL pointer dereference: [ 45.400843] Unregister pv shared memory for cpu 1 [ 45.412331] smpboot: CPU 1 is now offline [ 45.529894] SMP alternatives: lockdep: fixing up alternatives [ 45.533472] smpboot: Booting Node 0 Processor 1 APIC 0x1 [ 45.411526] kvm-clock: cpu 1, msr 0:7d14601, secondary cpu clock [ 45.571370] KVM setup async PF for cpu 1 [ 45.572331] kvm-stealtime: cpu 1, msr 7d0e040 [ 45.575031] BUG: unable to handle kernel NULL pointer dereference at (null) [ 45.576017] IP: [] cpuidle_disable_device+0x18/0x80 [ 45.576017] PGD 5dfb067 PUD 5da8067 PMD 0 [ 45.576017] Oops: 0000 [#1] SMP [ 45.576017] Modules linked in: [ 45.576017] CPU 0 [ 45.576017] Pid: 607, comm: stress_cpu_hotp Not tainted 3.6.0-padata-tp-debug #3 Bochs Bochs [ 45.576017] RIP: 0010:[] [] cpuidle_disable_device+0x18/0x80 [ 45.576017] RSP: 0018:ffff880005d93ce8 EFLAGS: 00010286 [ 45.576017] RAX: ffff880005d93fd8 RBX: 0000000000000000 RCX: 0000000000000006 [ 45.576017] RDX: 0000000000000006 RSI: 2222222222222222 RDI: 0000000000000000 [ 45.576017] RBP: ffff880005d93cf8 R08: 2222222222222222 R09: 2222222222222222 [ 45.576017] R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000 [ 45.576017] R13: 0000000000000000 R14: ffffffff81c8cca0 R15: 0000000000000001 [ 45.576017] FS: 00007f91936ae700(0000) GS:ffff880007c00000(0000) knlGS:0000000000000000 [ 45.576017] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b [ 45.576017] CR2: 0000000000000000 CR3: 0000000005db3000 CR4: 00000000000006f0 [ 45.576017] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 45.576017] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 [ 45.576017] Process stress_cpu_hotp (pid: 607, threadinfo ffff880005d92000, task ffff8800066bbf40) [ 45.576017] Stack: [ 45.576017] ffff880007a96400 0000000000000000 ffff880005d93d28 ffffffff813ac689 [ 45.576017] ffff880007a96400 ffff880007a96400 0000000000000002 ffffffff81cd8d01 [ 45.576017] ffff880005d93d58 ffffffff813aa498 0000000000000001 00000000ffffffdd [ 45.576017] Call Trace: [ 45.576017] [] acpi_processor_hotplug+0x55/0x97 [ 45.576017] [] acpi_cpu_soft_notify+0x93/0xce [ 45.576017] [] notifier_call_chain+0x5d/0x110 [ 45.576017] [] __raw_notifier_call_chain+0xe/0x10 [ 45.576017] [] __cpu_notify+0x20/0x40 [ 45.576017] [] cpu_notify+0x15/0x20 [ 45.576017] [] _cpu_up+0xee/0x137 [ 45.576017] [] cpu_up+0x49/0x59 [ 45.576017] [] store_online+0x9d/0xe0 [ 45.576017] [] dev_attr_store+0x18/0x30 [ 45.576017] [] sysfs_write_file+0xe0/0x150 [ 45.576017] [] vfs_write+0xac/0x180 [ 45.576017] [] sys_write+0x52/0xa0 [ 45.576017] [] system_call_fastpath+0x16/0x1b [ 45.576017] Code: 48 c7 c7 40 e5 ca 81 e8 07 d0 18 00 5d c3 0f 1f 44 00 00 0f 1f 44 00 00 55 48 89 e5 48 83 ec 10 48 89 5d f0 4c 89 65 f8 48 89 fb 07 02 75 13 48 8b 5d f0 4c 8b 65 f8 c9 c3 66 0f 1f 84 00 00 [ 45.576017] RIP [] cpuidle_disable_device+0x18/0x80 [ 45.576017] RSP [ 45.576017] CR2: 0000000000000000 [ 45.656079] ---[ end trace 433d6c9ac0b02cef ]--- Analysis: Commit 3d339dc (cpuidle / ACPI : move cpuidle_device field out of the acpi_processor_power structure()) made the allocation of the dev structure (struct cpuidle) of a CPU dynamic, whereas previously it was statically allocated. And this dynamic allocation occurs in acpi_processor_power_init() if pr->flags.power evaluates to non-zero. On KVM guests, pr->flags.power evaluates to zero, hence dev is never allocated. This causes the NULL pointer (dev) dereference in cpuidle_disable_device() during a subsequent CPU online operation. Fix this by ensuring that dev is non-NULL before dereferencing. Signed-off-by: Srivatsa S. Bhat Signed-off-by: Len Brown --- drivers/cpuidle/cpuidle.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index e28f6ea..7f15b85 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c @@ -368,7 +368,7 @@ EXPORT_SYMBOL_GPL(cpuidle_enable_device); */ void cpuidle_disable_device(struct cpuidle_device *dev) { - if (!dev->enabled) + if (!dev || !dev->enabled) return; if (!cpuidle_get_driver() || !cpuidle_curr_governor) return;