Skip to content
Snippets Groups Projects
Select Git revision
  • 4ce3c183fcade7f4b30a33dae90cd774c3d9e094
  • arm-dts-add-rkvdec-v2
  • add-vdpu381-and-383-to-rkvdec-v2
  • add-v4l2-st-lt-ref-set-support-v3
  • add-vdpu381-and-383-to-rkvdec
  • prepare-add-vdpu381-and-383-to-rkvdec
  • add-rkvdec2-driver-vdpu383-hevc
  • add-rkvdec2-driver-vdpu383
  • add-rkvdec2-driver-hevc
  • rkvdec-mov-to-structs
  • av1-fix-postproc-leak
  • add-rkvdec2-driver-iommu-422-10bits
  • patch-queue/jamba/trixie
  • hdmi-fix-1080p-rock4d-6.11
  • upstreaming/rk3576-rock4d-spi-v1
  • upstreaming/rk3576-rock4d-support-v5
  • upstreaming/rk3588-hdmi-audio-6
  • upstreaming/rk3576-rock4d-support-v3
  • upstreaming/rk3576-rock4d-support-v1
  • upstreaming/rk3576-rock4d-support
  • add-rkvdec2-driver-iommu
  • v6.3
  • v6.3-rc1
  • v6.2-rc1
  • v6.0-rc1
  • v5.19-rc3
  • v5.19-rc2
  • v5.19-rc1
  • v5.18
  • v5.18-rc7
  • v5.18-rc6
  • v5.18-rc5
  • v5.18-rc4
  • v5.18-rc3
  • v5.18-rc2
  • v5.18-rc1
  • v5.17
  • v5.17-rc8
  • v5.17-rc7
  • v5.17-rc6
  • v5.17-rc5
41 results

proc.c

Blame
  • Forked from hardware-enablement / Rockchip upstream enablement efforts / linux
    Source project has a limited visibility.
    syscall.c 2.56 KiB
    #include <linux/ptrace.h>
    #include <linux/sched.h>
    #include <linux/export.h>
    #include <asm/syscall.h>
    
    static int collect_syscall(struct task_struct *target, long *callno,
    			   unsigned long args[6], unsigned int maxargs,
    			   unsigned long *sp, unsigned long *pc)
    {
    	struct pt_regs *regs;
    
    	if (!try_get_task_stack(target)) {
    		/* Task has no stack, so the task isn't in a syscall. */
    		*callno = -1;
    		return 0;
    	}
    
    	regs = task_pt_regs(target);
    	if (unlikely(!regs)) {
    		put_task_stack(target);
    		return -EAGAIN;
    	}
    
    	*sp = user_stack_pointer(regs);
    	*pc = instruction_pointer(regs);
    
    	*callno = syscall_get_nr(target, regs);
    	if (*callno != -1L && maxargs > 0)
    		syscall_get_arguments(target, regs, 0, maxargs, args);
    
    	put_task_stack(target);
    	return 0;
    }
    
    /**
     * task_current_syscall - Discover what a blocked task is doing.
     * @target:		thread to examine
     * @callno:		filled with system call number or -1
     * @args:		filled with @maxargs system call arguments
     * @maxargs:		number of elements in @args to fill
     * @sp:			filled with user stack pointer
     * @pc:			filled with user PC
     *
     * If @target is blocked in a system call, returns zero with *@callno
     * set to the the call's number and @args filled in with its arguments.
     * Registers not used for system call arguments may not be available and
     * it is not kosher to use &struct user_regset calls while the system
     * call is still in progress.  Note we may get this result if @target
     * has finished its system call but not yet returned to user mode, such
     * as when it's stopped for signal handling or syscall exit tracing.
     *
     * If @target is blocked in the kernel during a fault or exception,
     * returns zero with *@callno set to -1 and does not fill in @args.
     * If so, it's now safe to examine @target using &struct user_regset
     * get() calls as long as we're sure @target won't return to user mode.
     *
     * Returns -%EAGAIN if @target does not remain blocked.
     *
     * Returns -%EINVAL if @maxargs is too large (maximum is six).
     */
    int task_current_syscall(struct task_struct *target, long *callno,
    			 unsigned long args[6], unsigned int maxargs,
    			 unsigned long *sp, unsigned long *pc)
    {
    	long state;
    	unsigned long ncsw;
    
    	if (unlikely(maxargs > 6))
    		return -EINVAL;
    
    	if (target == current)
    		return collect_syscall(target, callno, args, maxargs, sp, pc);
    
    	state = target->state;
    	if (unlikely(!state))
    		return -EAGAIN;
    
    	ncsw = wait_task_inactive(target, state);
    	if (unlikely(!ncsw) ||
    	    unlikely(collect_syscall(target, callno, args, maxargs, sp, pc)) ||
    	    unlikely(wait_task_inactive(target, state) != ncsw))
    		return -EAGAIN;
    
    	return 0;
    }