Skip to content
  • Yasuaki Ishimatsu's avatar
    drivers/firmware/memmap.c: don't allocate firmware_map_entry of same memory range · f0093ede
    Yasuaki Ishimatsu authored
    
    
    When limiting memory by mem= and ACPI DSDT table has PNP0C80,
    firmware_map_entrys of same memory range are allocated and memmap X
    sysfses which have same memory range are created as follows:
    
      # cat /sys/firmware/memmap/0/*
      0x407ffffffff
      0x40000000000
      System RAM
      # cat /sys/firmware/memmap/33/*
      0x407ffffffff
      0x40000000000
      System RAM
      # cat /sys/firmware/memmap/35/*
      0x407ffffffff
      0x40000000000
      System RAM
    
    In this case, when hot-removing memory, kernel panic occurs, showing
    following call trace:
    
      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 problem occurs as follows:
    
    When calling e820_reserve_resources(), firmware_map_entrys of all e820
    memory map are allocated.  And all firmware_map_entrys is added
    map_entries list as follows:
    
    map_entries
     -> +--- entry A --------+ -> ...
        | start 0x407ffffffff|
        | end   0x40000000000|
        | type  System RAM   |
        +--------------------+
    
    After that, if ACPI DSDT table has PNP0C80 and the memory range is
    limited by mem=, the PNP0C80 is hot-added.  Then firmware_map_entry of
    PNP0C80 is allocated and added map_entries list as follows:
    
    map_entries
     -> +--- entry A --------+ -> ... -> +--- entry B --------+
        | start 0x407ffffffff|           | start 0x407ffffffff|
        | end   0x40000000000|           | end   0x40000000000|
        | type  System RAM   |           | type  System RAM   |
        +--------------------+           +--------------------+
    
    Then memmap 0 sysfs for entry B is created.
    
    After that, firmware_memmap_init() creates memmap sysfses of all
    firmware_map_entrys in map_entries list.  As a result, memmap 33 sysfs
    for entry A and memmap 35 sysfs for entry B are created.  But kobject of
    entry B has been used by memmap 0 sysfs.  So when creating memmap 35
    sysfs, the kobject is broken.
    
    If hot-removing memory, memmap 0 sysfs is destroyed and kobject of
    memmap 0 sysfs is freed.  But the kobject can be accessed via memmap 35
    sysfs.  So when open memmap 35 sysfs, kernel panic occurs.
    
    This patch checks whether there is firmware_map_entry of same memory
    range in map_entries list and don't allocate firmware_map_entry of same
    memroy range.
    
    Signed-off-by: default avatarYasuaki 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: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    f0093ede