diff options
author | Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com> | 2014-10-09 15:29:07 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-10-09 22:26:00 -0400 |
commit | 22880ebe76be421a572b6f004604467c63f281f5 (patch) | |
tree | 0ee524463897136db4e313fa97bc080e94f4ac04 | |
parent | d85fbee89f6e67e37ed722adaf085f49b1ce6c50 (diff) |
drivers/firmware/memmap.c: don't create memmap sysfs of same firmware_map_entry
By the following commits, we prevented from allocating firmware_map_entry
of same memory range:
f0093ede: drivers/firmware/memmap.c: don't allocate firmware_map_entry
of same memory range
49c8b24d: drivers/firmware/memmap.c: pass the correct argument to
firmware_map_find_entry_bootmem()
But it's not enough. When PNP0C80 device is added by acpi_scan_init(),
memmap sysfses of same firmware_map_entry are created twice as follows:
# cat /sys/firmware/memmap/*/start
0x40000000000
0x60000000000
0x4a837000
0x4a83a000
0x4a8b5000
...
0x40000000000
0x60000000000
...
The flows of the issues are as follows:
1. e820_reserve_resources() allocates firmware_map_entrys of all
memory ranges defined in e820. And, these firmware_map_entrys
are linked with map_entries list.
map_entries -> entry 1 -> ... -> entry N
2. When PNP0C80 device is limited by mem= boot option, acpi_scan_init()
added the memory device. In this case, firmware_map_add_hotplug()
allocates firmware_map_entry and creates memmap sysfs.
map_entries -> entry 1 -> ... -> entry N -> entry N+1
|
memmap 1
3. firmware_memmap_init() creates memmap sysfses of firmware_map_entrys
linked with map_entries.
map_entries -> entry 1 -> ... -> entry N -> entry N+1
| | |
memmap 2 memmap N+1 memmap 1
memmap N+2
So while hot removing the PNP0C80 device, kernel panic occurs as follows:
BUG: unable to handle kernel paging request at 00000001003e000b
IP: sysfs_open_file+0x46/0x2b0
PGD 203a89fe067 PUD 0
Oops: 0000 [#1] SMP
...
Call Trace:
do_dentry_open+0x1ef/0x2a0
finish_open+0x31/0x40
do_last+0x57c/0x1220
path_openat+0xc2/0x4c0
do_filp_open+0x4b/0xb0
do_sys_open+0xf3/0x1f0
SyS_open+0x1e/0x20
system_call_fastpath+0x16/0x1b
The patch adds a check of confirming whether memmap sysfs of
firmware_map_entry has been created, and does not create memmap
sysfs of same firmware_map_entry.
Signed-off-by: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Toshi Kani <toshi.kani@hp.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | drivers/firmware/memmap.c | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/drivers/firmware/memmap.c b/drivers/firmware/memmap.c index 79f18e6d9c4f..cc016c615c19 100644 --- a/drivers/firmware/memmap.c +++ b/drivers/firmware/memmap.c @@ -184,6 +184,9 @@ static int add_sysfs_fw_map_entry(struct firmware_map_entry *entry) static int map_entries_nr; static struct kset *mmap_kset; + if (entry->kobj.state_in_sysfs) + return -EEXIST; + if (!mmap_kset) { mmap_kset = kset_create_and_add("memmap", NULL, firmware_kobj); if (!mmap_kset) |