• Dave Young's avatar
    mm: check pfn_valid first in zero_resv_unavail · e8c24773
    Dave Young authored
    With latest kernel I get below bug while testing kdump:
    
      BUG: unable to handle kernel paging request at ffffea00034b1040
      IP: zero_resv_unavail+0xbd/0x126
      PGD 37b98067 P4D 37b98067 PUD 37b97067 PMD 0
      Oops: 0002 [#1] SMP
      Modules linked in:
      CPU: 0 PID: 0 Comm: swapper Not tainted 4.15.0-rc1+ #316
      Hardware name: LENOVO 20ARS1BJ02/20ARS1BJ02, BIOS GJET92WW (2.42 ) 03/03/2017
      task: ffffffff81a0e4c0 task.stack: ffffffff81a00000
      RIP: 0010:zero_resv_unavail+0xbd/0x126
      RSP: 0000:ffffffff81a03d88 EFLAGS: 00010006
      RAX: 0000000000000000 RBX: ffffea00034b1040 RCX: 0000000000000010
      RDX: 0000000000000000 RSI: 0000000000000092 RDI: ffffea00034b1040
      RBP: 00000000000d2c41 R08: 00000000000000c0 R09: 0000000000000a0d
      R10: 0000000000000002 R11: 0000000000007f01 R12: ffffffff81a03d90
      R13: ffffea0000000000 R14: 0000000000000063 R15: 0000000000000062
      FS:  0000000000000000(0000) GS:ffffffff81c73000(0000) knlGS:0000000000000000
      CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
      CR2: ffffea00034b1040 CR3: 0000000037609000 CR4: 00000000000606b0
      Call Trace:
       ? free_area_init_nodes+0x640/0x664
       ? zone_sizes_init+0x58/0x72
       ? setup_arch+0xb50/0xc6c
       ? start_kernel+0x64/0x43d
       ? secondary_startup_64+0xa5/0xb0
      Code: c1 e8 0c 48 39 d8 76 27 48 89 de 48 c1 e3 06 48 c7 c7 7a 87 79 81 e8 b0 c0 3e ff 4c 01 eb b9 10 00 00 00 31 c0 48 89 df 49 ff c6 <f3> ab eb bc 6a 00 49 c7 c0 f0 93 d1 81 31 d2 83 ce ff 41 54 49
      RIP: zero_resv_unavail+0xbd/0x126 RSP: ffffffff81a03d88
      CR2: ffffea00034b1040
      ---[ end trace f5ba9e8f73c7ee26 ]---
    
    This is introduced by commit a4a3ede2 ("mm: zero reserved and
    unavailable struct pages").
    
    The reason is some efi reserved boot ranges is not reported in E820 ram.
    In my case it is a bgrt buffer:
    
      efi: mem00: [Boot Data          |RUN|  |  |  |  |  |  |   |WB|WT|WC|UC] range=[0x00000000d2c41000-0x00000000d2c85fff] (0MB)
    
    Use "add_efi_memmap" can workaround the problem with another fix:
    
      http://lkml.kernel.org/r/20171130052327.GA3500@dhcp-128-65.nay.redhat.com
    
    In zero_resv_unavail it would be better to check pfn_valid first before
    zero the page struct.  This fixes the problem and potential other
    similar problems.  Also as Pavel Tatashin suggested checks pfn_valid at
    the beginning of the section.
    
    The range is backed by real memory.  The memory range is efi "Boot
    Service Data", that means after ExitBootServices() these ranges can be
    used as system ram.  But some of them need to be reserved, for example
    the bgrt image address in an acpi table, if the image memory is freed
    then kexec reboot will fail because kexec inherit same acpi table to
    initialize the driver.
    
    Link: http://lkml.kernel.org/r/20171201095048.GA3084@dhcp-128-65.nay.redhat.com
    Fixes: a4a3ede2 ("mm: zero reserved and unavailable struct pages")
    Signed-off-by: default avatarDave Young <dyoung@redhat.com>
    Cc: Michal Hocko <mhocko@kernel.org>
    Cc: Pavel Tatashin <pasha.tatashin@oracle.com>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    e8c24773
page_alloc.c 214 KB