Revision 0228ecf6128c92b47eadd2ac270c5574d9150c09 authored by Paul Burton on 01 October 2019, 21:56:37 UTC, committed by Paul Burton on 02 October 2019, 17:08:20 UTC
Commit 171a9bae68c7 ("staging/octeon: Allow test build on !MIPS") moved
the inclusion of a bunch of headers by various files in the Octeon
ethernet driver into a common header, but in doing so it changed the
order in which those headers are included.

Prior to the referenced commit drivers/staging/octeon/ethernet.c
included asm/octeon/cvmx-pip.h before asm/octeon/cvmx-ipd.h, which makes
use of the CVMX_PIP_SFT_RST definition pulled in by the former. After
commit 171a9bae68c7 ("staging/octeon: Allow test build on !MIPS") we
pull in asm/octeon/cvmx-ipd.h first & builds fail with:

  In file included from drivers/staging/octeon/octeon-ethernet.h:27,
                   from drivers/staging/octeon/ethernet.c:22:
  arch/mips/include/asm/octeon/cvmx-ipd.h: In function 'cvmx_ipd_free_ptr':
  arch/mips/include/asm/octeon/cvmx-ipd.h:330:27: error: storage size of
    'pip_sft_rst' isn't known
      union cvmx_pip_sft_rst pip_sft_rst;
                             ^~~~~~~~~~~
  arch/mips/include/asm/octeon/cvmx-ipd.h:331:36: error: 'CVMX_PIP_SFT_RST'
    undeclared (first use in this function); did you mean 'CVMX_CIU_SOFT_RST'?
      pip_sft_rst.u64 = cvmx_read_csr(CVMX_PIP_SFT_RST);
                                      ^~~~~~~~~~~~~~~~
                                      CVMX_CIU_SOFT_RST
  arch/mips/include/asm/octeon/cvmx-ipd.h:331:36: note: each undeclared
    identifier is reported only once for each function it appears in
  arch/mips/include/asm/octeon/cvmx-ipd.h:330:27: warning: unused variable
    'pip_sft_rst' [-Wunused-variable]
      union cvmx_pip_sft_rst pip_sft_rst;
                             ^~~~~~~~~~~
  make[4]: *** [scripts/Makefile.build:266: drivers/staging/octeon/ethernet.o]
    Error 1
  make[3]: *** [scripts/Makefile.build:509: drivers/staging/octeon] Error 2

Fix this by having asm/octeon/cvmx-ipd.h include the
asm/octeon/cvmx-pip-defs.h header that it is reliant upon, rather than
requiring its users to pull in that header before it.

Signed-off-by: Paul Burton <paul.burton@mips.com>
Fixes: 171a9bae68c7 ("staging/octeon: Allow test build on !MIPS")
Cc: David S. Miller <davem@davemloft.net>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: linux-mips@vger.kernel.org
Cc: David S . Miller <davem@davemloft.net>
Cc: Matthew Wilcox <willy@infradead.org>
1 parent d345d9c
Raw File
syscall.c
// SPDX-License-Identifier: GPL-2.0
#include <linux/ptrace.h>
#include <linux/sched.h>
#include <linux/sched/task_stack.h>
#include <linux/export.h>
#include <asm/syscall.h>

static int collect_syscall(struct task_struct *target, struct syscall_info *info)
{
	struct pt_regs *regs;

	if (!try_get_task_stack(target)) {
		/* Task has no stack, so the task isn't in a syscall. */
		memset(info, 0, sizeof(*info));
		info->data.nr = -1;
		return 0;
	}

	regs = task_pt_regs(target);
	if (unlikely(!regs)) {
		put_task_stack(target);
		return -EAGAIN;
	}

	info->sp = user_stack_pointer(regs);
	info->data.instruction_pointer = instruction_pointer(regs);

	info->data.nr = syscall_get_nr(target, regs);
	if (info->data.nr != -1L)
		syscall_get_arguments(target, regs,
				      (unsigned long *)&info->data.args[0]);

	put_task_stack(target);
	return 0;
}

/**
 * task_current_syscall - Discover what a blocked task is doing.
 * @target:		thread to examine
 * @info:		structure with the following fields:
 *			 .sp        - filled with user stack pointer
 *			 .data.nr   - filled with system call number or -1
 *			 .data.args - filled with @maxargs system call arguments
 *			 .data.instruction_pointer - filled with user PC
 *
 * If @target is blocked in a system call, returns zero with @info.data.nr
 * set to the the call's number and @info.data.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 *@info.data.nr set to -1 and does not fill in
 * @info.data.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.
 */
int task_current_syscall(struct task_struct *target, struct syscall_info *info)
{
	long state;
	unsigned long ncsw;

	if (target == current)
		return collect_syscall(target, info);

	state = target->state;
	if (unlikely(!state))
		return -EAGAIN;

	ncsw = wait_task_inactive(target, state);
	if (unlikely(!ncsw) ||
	    unlikely(collect_syscall(target, info)) ||
	    unlikely(wait_task_inactive(target, state) != ncsw))
		return -EAGAIN;

	return 0;
}
back to top