From: Alex Chiang Date: Thu, 21 May 2009 22:21:15 +0000 (-0600) Subject: PCI Hotplug: acpiphp: don't store a pci_dev in acpiphp_func X-Git-Tag: v2.6.30-rc8~16^2 X-Git-Url: http://git.openpandora.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9d911d7903926a65ef49ec671bacd86bcee5eb51;p=pandora-kernel.git PCI Hotplug: acpiphp: don't store a pci_dev in acpiphp_func An oops can occur if a user attempts to use both PCI logical hotplug and the ACPI physical hotplug driver (acpiphp) in this sequence, where $slot/address == $device. In other words, if acpiphp has claimed a PCI device, and that device is logically removed, then acpiphp may oops when it attempts to access it again. # echo 1 > /sys/bus/pci/devices/$device/remove # echo 0 > /sys/bus/pci/slots/$slot/power Unable to handle kernel NULL pointer dereference (address 0000000000000000) Call Trace: [] show_stack+0x50/0xa0 [] show_regs+0x820/0x860 [] die+0x190/0x2a0 [] ia64_do_page_fault+0x8e0/0xa40 [] ia64_native_leave_kernel+0x0/0x270 [] pci_remove_bus_device+0x120/0x260 [] acpiphp_disable_slot+0x410/0x540 [acpiphp] [] disable_slot+0xc0/0x120 [acpiphp] [] power_write_file+0x1e0/0x2a0 [pci_hotplug] [] pci_slot_attr_store+0x60/0xa0 [] sysfs_write_file+0x230/0x2c0 [] vfs_write+0x190/0x2e0 [] sys_write+0x80/0x100 [] ia64_ret_from_syscall+0x0/0x20 [] __kernel_syscall_via_break+0x0/0x20 The root cause of this oops is that the logical remove ("echo 1 > /sys/bus/pci/devices/$device/remove") destroyed the pci_dev. The pci_dev struct itself wasn't deallocated because acpiphp kept a reference, but some of its fields became invalid. acpiphp doesn't have any real reason to keep a pointer to a pci_dev around. It can always derive it using pci_get_slot(). If a logical remove destroys the pci_dev, acpiphp won't find it and is thus prevented from causing mischief. Reviewed-by: Matthew Wilcox Reviewed-by: Kenji Kaneshige Tested-by: Kenji Kaneshige Reported-by: Kenji Kaneshige Acked-by: Bjorn Helgaas Signed-off-by: Alex Chiang Signed-off-by: Jesse Barnes --- Reading git-diff-tree failed