• Athira Rajeev's avatar
    powerpc/pseries: Fix STK_PARAM access in the hcall tracing code · 3b678768
    Athira Rajeev authored
    In powerpc pseries system, below behaviour is observed while
    enabling tracing on hcall:
      # cd /sys/kernel/debug/tracing/
      # cat events/powerpc/hcall_exit/enable
      0
      # echo 1 > events/powerpc/hcall_exit/enable
    
      # ls
      -bash: fork: Bad address
    
    Above is from power9 lpar with latest kernel. Past this, softlockup
    is observed. Initially while attempting via perf_event_open to
    use "PERF_TYPE_TRACEPOINT", kernel panic was observed.
    
    perf config used:
    ================
      memset(&pe[1],0,sizeof(struct perf_event_attr));
      pe[1].type=PERF_TYPE_TRACEPOINT;
      pe[1].size=96;
      pe[1].config=0x26ULL; /* 38 raw_syscalls/sys_exit */
      pe[1].sample_type=0; /* 0 */
      pe[1].read_format=PERF_FORMAT_TOTAL_TIME_ENABLED|PERF_FORMAT_TOTAL_TIME_RUNNING|PERF_FORMAT_ID|PERF_FORMAT_GROUP|0x10ULL; /* 1f */
      pe[1].inherit=1;
      pe[1].precise_ip=0; /* arbitrary skid */
      pe[1].wakeup_events=0;
      pe[1].bp_type=HW_BREAKPOINT_EMPTY;
      pe[1].config1=0x1ULL;
    
    Kernel panic logs:
    ==================
    
      Kernel attempted to read user page (8) - exploit attempt? (uid: 0)
      BUG: Kernel NULL pointer dereference on read at 0x00000008
      Faulting instruction address: 0xc0000000004c2814
      Oops: Kernel access of bad area, sig: 11 [#1]
      LE PAGE_SIZE=64K MMU=Hash SMP NR_CPUS=2048 NUMA pSeries
      Modules linked in: nfnetlink bonding tls rfkill sunrpc dm_service_time dm_multipath pseries_rng xts vmx_crypto xfs libcrc32c sd_mod t10_pi crc64_rocksoft crc64 sg ibmvfc scsi_transport_fc ibmveth dm_mirror dm_region_hash dm_log dm_mod fuse
      CPU: 0 PID: 1431 Comm: login Not tainted 6.4.0+ #1
      Hardware name: IBM,8375-42A POWER9 (raw) 0x4e0202 0xf000005 of:IBM,FW950.30 (VL950_892) hv:phyp pSeries
      NIP page_remove_rmap+0x44/0x320
      LR  wp_page_copy+0x384/0xec0
      Call Trace:
        0xc00000001416e400 (unreliable)
        wp_page_copy+0x384/0xec0
        __handle_mm_fault+0x9d4/0xfb0
        handle_mm_fault+0xf0/0x350
        ___do_page_fault+0x48c/0xc90
        hash__do_page_fault+0x30/0x70
        do_hash_fault+0x1a4/0x330
        data_access_common_virt+0x198/0x1f0
       --- interrupt: 300 at 0x7fffae971abc
    
    git bisect tracked this down to below commit:
    'commit baa49d81 ("powerpc/pseries: hvcall stack frame overhead")'
    
    This commit changed STACK_FRAME_OVERHEAD (112 ) to
    STACK_FRAME_MIN_SIZE (32 ) since 32 bytes is the minimum size
    for ELFv2 stack. With the latest kernel, when running on ELFv2,
    STACK_FRAME_MIN_SIZE is used to allocate stack size.
    
    During plpar_hcall_trace, first call is made to HCALL_INST_PRECALL
    which saves the registers and allocates new stack frame. In the
    plpar_hcall_trace code, STK_PARAM is accessed at two places.
      1. To save r4: std     r4,STK_PARAM(R4)(r1)
      2. To access r4 back: ld      r12,STK_PARAM(R4)(r1)
    
    HCALL_INST_PRECALL precall allocates a new stack frame. So all
    the stack parameter access after the precall, needs to be accessed
    with +STACK_FRAME_MIN_SIZE. So the store instruction should be:
      std     r4,STACK_FRAME_MIN_SIZE+STK_PARAM(R4)(r1)
    
    If the "std" is not updated with STACK_FRAME_MIN_SIZE, we will
    end up with overwriting stack contents and cause corruption.
    But instead of updating 'std', we can instead remove it since
    HCALL_INST_PRECALL already saves it to the correct location.
    
    similarly load instruction should be:
      ld      r12,STACK_FRAME_MIN_SIZE+STK_PARAM(R4)(r1)
    
    Fix the load instruction to correctly access the stack parameter
    with +STACK_FRAME_MIN_SIZE and remove the store of r4 since the
    precall saves it correctly.
    
    Cc: stable@vger.kernel.org # v6.2+
    Fixes: baa49d81
    
     ("powerpc/pseries: hvcall stack frame overhead")
    Co-developed-by: default avatarNaveen N Rao <naveen@kernel.org>
    Signed-off-by: default avatarNaveen N Rao <naveen@kernel.org>
    Signed-off-by: default avatarAthira Rajeev <atrajeev@linux.vnet.ibm.com>
    Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
    Link: https://msgid.link/20230929172337.7906-1-atrajeev@linux.vnet.ibm.com
    3b678768
hvCall.S 6.83 KB