• Laurent Dufour's avatar
    powerpc/pseries: Call H_BLOCK_REMOVE when supported · 59545ebe
    Laurent Dufour authored
    Depending on the hardware and the hypervisor, the hcall H_BLOCK_REMOVE
    may not be able to process all the page sizes for a segment base page
    size, as reported by the TLB Invalidate Characteristics.
    
    For each pair of base segment page size and actual page size, this
    characteristic tells us the size of the block the hcall supports.
    
    In the case, the hcall is not supporting a pair of base segment page
    size, actual page size, it is returning H_PARAM which leads to a panic
    like this:
    
      kernel BUG at /home/srikar/work/linux.git/arch/powerpc/platforms/pseries/lpar.c:466!
      Oops: Exception in kernel mode, sig: 5 [#1]
      BE PAGE_SIZE=64K MMU=Hash SMP NR_CPUS=2048 NUMA pSeries
      Modules linked in:
      CPU: 28 PID: 583 Comm: modprobe Not tainted 5.2.0-master #5
      NIP: c0000000000be8dc LR: c0000000000be880 CTR: 0000000000000000
      REGS: c0000007e77fb130 TRAP: 0700  Not tainted (5.2.0-master)
      MSR: 8000000000029032 <SF,EE,ME,IR,DR,RI> CR: 42224824 XER: 20000000
      CFAR: c0000000000be8fc IRQMASK: 0
      GPR00: 0000000022224828 c0000007e77fb3c0 c000000001434d00 0000000000000005
      GPR04: 9000000004fa8c00 0000000000000000 0000000000000003 0000000000000001
      GPR08: c0000007e77fb450 0000000000000000 0000000000000001 ffffffffffffffff
      GPR12: c0000007e77fb450 c00000000edfcb80 0000cd7d3ea30000 c0000000016022b0
      GPR16: 00000000000000b0 0000cd7d3ea30000 0000000000000001 c080001f04f00105
      GPR20: 0000000000000003 0000000000000004 c000000fbeb05f58 c000000001602200
      GPR24: 0000000000000000 0000000000000004 8800000000000000 c000000000c5d148
      GPR28: c000000000000000 8000000000000000 a000000000000000 c0000007e77fb580
      NIP [c0000000000be8dc] .call_block_remove+0x12c/0x220
      LR [c0000000000be880] .call_block_remove+0xd0/0x220
      Call Trace:
        0xc000000fb8c00240 (unreliable)
        .pSeries_lpar_flush_hash_range+0x578/0x670
        .flush_hash_range+0x44/0x100
        .__flush_tlb_pending+0x3c/0xc0
        .zap_pte_range+0x7ec/0x830
        .unmap_page_range+0x3f4/0x540
        .unmap_vmas+0x94/0x120
        .exit_mmap+0xac/0x1f0
        .mmput+0x9c/0x1f0
        .do_exit+0x388/0xd60
        .do_group_exit+0x54/0x100
        .__se_sys_exit_group+0x14/0x20
        system_call+0x5c/0x70
      Instruction dump:
      39400001 38a00000 4800003c 60000000 60420000 7fa9e800 38e00000 419e0014
      7d29d278 7d290074 7929d182 69270001 <0b070000> 7d495378 394a0001 7fa93040
    
    The call to H_BLOCK_REMOVE should only be made for the supported pair
    of base segment page size, actual page size and using the correct
    maximum block size.
    
    Due to the required complexity in do_block_remove() and
    call_block_remove(), and the fact that currently a block size of 8 is
    returned by the hypervisor, we are only supporting 8 size block to the
    H_BLOCK_REMOVE hcall.
    
    In order to identify this limitation easily in the code, a local
    define HBLKR_SUPPORTED_SIZE defining the currently supported block
    size, and a dedicated checking helper is_supported_hlbkr() are
    introduced.
    
    For regular pages and hugetlb, the assumption is made that the page
    size is equal to the base page size. For THP the page size is assumed
    to be 16M.
    
    Fixes: ba2dd8a2 ("powerpc/pseries/mm: call H_BLOCK_REMOVE")
    Signed-off-by: default avatarLaurent Dufour <ldufour@linux.ibm.com>
    Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
    Link: https://lore.kernel.org/r/20190920130523.20441-3-ldufour@linux.ibm.com
    59545ebe
lpar.c 49.8 KB