aboutsummaryrefslogtreecommitdiffstats
path: root/arch/xtensa/include/asm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/xtensa/include/asm')
-rw-r--r--arch/xtensa/include/asm/Kbuild1
-rw-r--r--arch/xtensa/include/asm/coprocessor.h23
-rw-r--r--arch/xtensa/include/asm/elf.h33
-rw-r--r--arch/xtensa/include/asm/futex.h8
-rw-r--r--arch/xtensa/include/asm/irqflags.h1
-rw-r--r--arch/xtensa/include/asm/jump_label.h65
-rw-r--r--arch/xtensa/include/asm/processor.h18
-rw-r--r--arch/xtensa/include/asm/ptrace.h7
-rw-r--r--arch/xtensa/include/asm/syscall.h109
-rw-r--r--arch/xtensa/include/asm/thread_info.h9
-rw-r--r--arch/xtensa/include/asm/timex.h18
-rw-r--r--arch/xtensa/include/asm/traps.h2
-rw-r--r--arch/xtensa/include/asm/uaccess.h10
-rw-r--r--arch/xtensa/include/asm/unistd.h2
14 files changed, 204 insertions, 102 deletions
diff --git a/arch/xtensa/include/asm/Kbuild b/arch/xtensa/include/asm/Kbuild
index 3310adecafb0..e255683cd520 100644
--- a/arch/xtensa/include/asm/Kbuild
+++ b/arch/xtensa/include/asm/Kbuild
@@ -1,3 +1,4 @@
+generated-y += syscall_table.h
generic-y += bug.h
generic-y += compat.h
generic-y += device.h
diff --git a/arch/xtensa/include/asm/coprocessor.h b/arch/xtensa/include/asm/coprocessor.h
index 677501b32dfc..6712929a27c9 100644
--- a/arch/xtensa/include/asm/coprocessor.h
+++ b/arch/xtensa/include/asm/coprocessor.h
@@ -12,7 +12,6 @@
#ifndef _XTENSA_COPROCESSOR_H
#define _XTENSA_COPROCESSOR_H
-#include <linux/stringify.h>
#include <variant/core.h>
#include <variant/tie.h>
#include <asm/types.h>
@@ -90,19 +89,6 @@
#ifndef __ASSEMBLY__
-
-#if XCHAL_HAVE_CP
-
-#define RSR_CPENABLE(x) do { \
- __asm__ __volatile__("rsr %0, cpenable" : "=a" (x)); \
- } while(0);
-#define WSR_CPENABLE(x) do { \
- __asm__ __volatile__("wsr %0, cpenable; rsync" :: "a" (x)); \
- } while(0);
-
-#endif /* XCHAL_HAVE_CP */
-
-
/*
* Additional registers.
* We define three types of additional registers:
@@ -157,20 +143,11 @@ typedef struct { XCHAL_CP7_SA_LIST(2) } xtregs_cp7_t
__attribute__ ((aligned (XCHAL_CP7_SA_ALIGN)));
extern struct thread_info* coprocessor_owner[XCHAL_CP_MAX];
-extern void coprocessor_save(void*, int);
-extern void coprocessor_load(void*, int);
extern void coprocessor_flush(struct thread_info*, int);
-extern void coprocessor_restore(struct thread_info*, int);
extern void coprocessor_release_all(struct thread_info*);
extern void coprocessor_flush_all(struct thread_info*);
-static inline void coprocessor_clear_cpenable(void)
-{
- unsigned long i = 0;
- WSR_CPENABLE(i);
-}
-
#endif /* XTENSA_HAVE_COPROCESSORS */
#endif /* !__ASSEMBLY__ */
diff --git a/arch/xtensa/include/asm/elf.h b/arch/xtensa/include/asm/elf.h
index eacb25a41718..909a6ab4f22b 100644
--- a/arch/xtensa/include/asm/elf.h
+++ b/arch/xtensa/include/asm/elf.h
@@ -15,10 +15,10 @@
#include <asm/ptrace.h>
#include <asm/coprocessor.h>
+#include <linux/elf-em.h>
/* Xtensa processor ELF architecture-magic number */
-#define EM_XTENSA 94
#define EM_XTENSA_OLD 0xABC7
/* Xtensa relocations defined by the ABIs */
@@ -75,19 +75,7 @@
typedef unsigned long elf_greg_t;
-typedef struct {
- elf_greg_t pc;
- elf_greg_t ps;
- elf_greg_t lbeg;
- elf_greg_t lend;
- elf_greg_t lcount;
- elf_greg_t sar;
- elf_greg_t windowstart;
- elf_greg_t windowbase;
- elf_greg_t threadptr;
- elf_greg_t reserved[7+48];
- elf_greg_t a[64];
-} xtensa_gregset_t;
+typedef struct user_pt_regs xtensa_gregset_t;
#define ELF_NGREG (sizeof(xtensa_gregset_t) / sizeof(elf_greg_t))
@@ -98,11 +86,6 @@ typedef elf_greg_t elf_gregset_t[ELF_NGREG];
typedef unsigned int elf_fpreg_t;
typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
-#define ELF_CORE_COPY_REGS(_eregs, _pregs) \
- xtensa_elf_core_copy_regs ((xtensa_gregset_t*)&(_eregs), _pregs);
-
-extern void xtensa_elf_core_copy_regs (xtensa_gregset_t *, struct pt_regs *);
-
/*
* This is used to ensure we don't load something for the wrong architecture.
*/
@@ -126,6 +109,7 @@ extern void xtensa_elf_core_copy_regs (xtensa_gregset_t *, struct pt_regs *);
#define ELF_ARCH EM_XTENSA
#define ELF_EXEC_PAGESIZE PAGE_SIZE
+#define CORE_DUMP_USE_REGSET
/*
* This is the location that an ET_DYN program is loaded if exec'ed. Typical
@@ -193,15 +177,4 @@ typedef struct {
#define SET_PERSONALITY(ex) \
set_personality(PER_LINUX_32BIT | (current->personality & (~PER_MASK)))
-struct task_struct;
-
-extern void do_copy_regs (xtensa_gregset_t*, struct pt_regs*,
- struct task_struct*);
-extern void do_restore_regs (xtensa_gregset_t*, struct pt_regs*,
- struct task_struct*);
-extern void do_save_fpregs (elf_fpregset_t*, struct pt_regs*,
- struct task_struct*);
-extern int do_restore_fpregs (elf_fpregset_t*, struct pt_regs*,
- struct task_struct*);
-
#endif /* _XTENSA_ELF_H */
diff --git a/arch/xtensa/include/asm/futex.h b/arch/xtensa/include/asm/futex.h
index 5bfbc1c401d4..fd0eef6b8e7c 100644
--- a/arch/xtensa/include/asm/futex.h
+++ b/arch/xtensa/include/asm/futex.h
@@ -32,8 +32,8 @@
"3:\n" \
" .section .fixup,\"ax\"\n" \
" .align 4\n" \
- "4: .long 3b\n" \
- "5: l32r %0, 4b\n" \
+ " .literal_position\n" \
+ "5: movi %0, 3b\n" \
" movi %1, %3\n" \
" jx %0\n" \
" .previous\n" \
@@ -108,8 +108,8 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
"2:\n"
" .section .fixup,\"ax\"\n"
" .align 4\n"
- "3: .long 2b\n"
- "4: l32r %1, 3b\n"
+ " .literal_position\n"
+ "4: movi %1, 2b\n"
" movi %0, %7\n"
" jx %1\n"
" .previous\n"
diff --git a/arch/xtensa/include/asm/irqflags.h b/arch/xtensa/include/asm/irqflags.h
index 407606e576f8..9b5e8526afe5 100644
--- a/arch/xtensa/include/asm/irqflags.h
+++ b/arch/xtensa/include/asm/irqflags.h
@@ -12,6 +12,7 @@
#ifndef _XTENSA_IRQFLAGS_H
#define _XTENSA_IRQFLAGS_H
+#include <linux/stringify.h>
#include <linux/types.h>
#include <asm/processor.h>
diff --git a/arch/xtensa/include/asm/jump_label.h b/arch/xtensa/include/asm/jump_label.h
new file mode 100644
index 000000000000..c812bf85021c
--- /dev/null
+++ b/arch/xtensa/include/asm/jump_label.h
@@ -0,0 +1,65 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (C) 2018 Cadence Design Systems Inc. */
+
+#ifndef _ASM_XTENSA_JUMP_LABEL_H
+#define _ASM_XTENSA_JUMP_LABEL_H
+
+#ifndef __ASSEMBLY__
+
+#include <linux/types.h>
+
+#define JUMP_LABEL_NOP_SIZE 3
+
+static __always_inline bool arch_static_branch(struct static_key *key,
+ bool branch)
+{
+ asm_volatile_goto("1:\n\t"
+ "_nop\n\t"
+ ".pushsection __jump_table, \"aw\"\n\t"
+ ".word 1b, %l[l_yes], %c0\n\t"
+ ".popsection\n\t"
+ : : "i" (&((char *)key)[branch]) : : l_yes);
+
+ return false;
+l_yes:
+ return true;
+}
+
+static __always_inline bool arch_static_branch_jump(struct static_key *key,
+ bool branch)
+{
+ /*
+ * Xtensa assembler will mark certain points in the code
+ * as unreachable, so that later assembler or linker relaxation
+ * passes could use them. A spot right after the J instruction
+ * is one such point. Assembler and/or linker may insert padding
+ * or literals here, breaking code flow in case the J instruction
+ * is later replaced with NOP. Put a label right after the J to
+ * make it reachable and wrap both into a no-transform block
+ * to avoid any assembler interference with this.
+ */
+ asm_volatile_goto("1:\n\t"
+ ".begin no-transform\n\t"
+ "_j %l[l_yes]\n\t"
+ "2:\n\t"
+ ".end no-transform\n\t"
+ ".pushsection __jump_table, \"aw\"\n\t"
+ ".word 1b, %l[l_yes], %c0\n\t"
+ ".popsection\n\t"
+ : : "i" (&((char *)key)[branch]) : : l_yes);
+
+ return false;
+l_yes:
+ return true;
+}
+
+typedef u32 jump_label_t;
+
+struct jump_entry {
+ jump_label_t code;
+ jump_label_t target;
+ jump_label_t key;
+};
+
+#endif /* __ASSEMBLY__ */
+#endif
diff --git a/arch/xtensa/include/asm/processor.h b/arch/xtensa/include/asm/processor.h
index 34a23016dd14..f7dd895b2353 100644
--- a/arch/xtensa/include/asm/processor.h
+++ b/arch/xtensa/include/asm/processor.h
@@ -13,6 +13,7 @@
#include <variant/core.h>
#include <linux/compiler.h>
+#include <linux/stringify.h>
#include <asm/ptrace.h>
#include <asm/types.h>
#include <asm/regs.h>
@@ -212,11 +213,18 @@ extern unsigned long get_wchan(struct task_struct *p);
/* Special register access. */
-#define WSR(v,sr) __asm__ __volatile__ ("wsr %0,"__stringify(sr) :: "a"(v));
-#define RSR(v,sr) __asm__ __volatile__ ("rsr %0,"__stringify(sr) : "=a"(v));
-
-#define set_sr(x,sr) ({unsigned int v=(unsigned int)x; WSR(v,sr);})
-#define get_sr(sr) ({unsigned int v; RSR(v,sr); v; })
+#define xtensa_set_sr(x, sr) \
+ ({ \
+ unsigned int v = (unsigned int)(x); \
+ __asm__ __volatile__ ("wsr %0, "__stringify(sr) :: "a"(v)); \
+ })
+
+#define xtensa_get_sr(sr) \
+ ({ \
+ unsigned int v; \
+ __asm__ __volatile__ ("rsr %0, "__stringify(sr) : "=a"(v)); \
+ v; \
+ })
#ifndef XCHAL_HAVE_EXTERN_REGS
#define XCHAL_HAVE_EXTERN_REGS 0
diff --git a/arch/xtensa/include/asm/ptrace.h b/arch/xtensa/include/asm/ptrace.h
index 3a5c5918aea3..62a58d2567e9 100644
--- a/arch/xtensa/include/asm/ptrace.h
+++ b/arch/xtensa/include/asm/ptrace.h
@@ -39,6 +39,8 @@
* +-----------------------+ --------
*/
+#define NO_SYSCALL (-1)
+
#ifndef __ASSEMBLY__
#include <asm/coprocessor.h>
@@ -100,6 +102,11 @@ struct pt_regs {
#define user_stack_pointer(regs) ((regs)->areg[1])
+static inline unsigned long regs_return_value(struct pt_regs *regs)
+{
+ return regs->areg[2];
+}
+
#else /* __ASSEMBLY__ */
# include <asm/asm-offsets.h>
diff --git a/arch/xtensa/include/asm/syscall.h b/arch/xtensa/include/asm/syscall.h
index 3673ff1f1bc5..a168bf81c7f4 100644
--- a/arch/xtensa/include/asm/syscall.h
+++ b/arch/xtensa/include/asm/syscall.h
@@ -1,27 +1,108 @@
/*
- * include/asm-xtensa/syscall.h
- *
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 2001 - 2007 Tensilica Inc.
+ * Copyright (C) 2018 Cadence Design Systems Inc.
*/
-struct pt_regs;
-asmlinkage long xtensa_ptrace(long, long, long, long);
-asmlinkage long xtensa_sigreturn(struct pt_regs*);
+#ifndef _ASM_SYSCALL_H
+#define _ASM_SYSCALL_H
+
+#include <linux/err.h>
+#include <asm/ptrace.h>
+#include <uapi/linux/audit.h>
+
+static inline int syscall_get_arch(void)
+{
+ return AUDIT_ARCH_XTENSA;
+}
+
+typedef void (*syscall_t)(void);
+extern syscall_t sys_call_table[];
+
+static inline long syscall_get_nr(struct task_struct *task,
+ struct pt_regs *regs)
+{
+ return regs->syscall;
+}
+
+static inline void syscall_rollback(struct task_struct *task,
+ struct pt_regs *regs)
+{
+ /* Do nothing. */
+}
+
+static inline long syscall_get_error(struct task_struct *task,
+ struct pt_regs *regs)
+{
+ /* 0 if syscall succeeded, otherwise -Errorcode */
+ return IS_ERR_VALUE(regs->areg[2]) ? regs->areg[2] : 0;
+}
+
+static inline long syscall_get_return_value(struct task_struct *task,
+ struct pt_regs *regs)
+{
+ return regs->areg[2];
+}
+
+static inline void syscall_set_return_value(struct task_struct *task,
+ struct pt_regs *regs,
+ int error, long val)
+{
+ regs->areg[0] = (long) error ? error : val;
+}
+
+#define SYSCALL_MAX_ARGS 6
+#define XTENSA_SYSCALL_ARGUMENT_REGS {6, 3, 4, 5, 8, 9}
+
+static inline void syscall_get_arguments(struct task_struct *task,
+ struct pt_regs *regs,
+ unsigned int i, unsigned int n,
+ unsigned long *args)
+{
+ static const unsigned int reg[] = XTENSA_SYSCALL_ARGUMENT_REGS;
+ unsigned int j;
+
+ if (n == 0)
+ return;
+
+ WARN_ON_ONCE(i + n > SYSCALL_MAX_ARGS);
+
+ for (j = 0; j < n; ++j) {
+ if (i + j < SYSCALL_MAX_ARGS)
+ args[j] = regs->areg[reg[i + j]];
+ else
+ args[j] = 0;
+ }
+}
+
+static inline void syscall_set_arguments(struct task_struct *task,
+ struct pt_regs *regs,
+ unsigned int i, unsigned int n,
+ const unsigned long *args)
+{
+ static const unsigned int reg[] = XTENSA_SYSCALL_ARGUMENT_REGS;
+ unsigned int j;
+
+ if (n == 0)
+ return;
+
+ if (WARN_ON_ONCE(i + n > SYSCALL_MAX_ARGS)) {
+ if (i < SYSCALL_MAX_ARGS)
+ n = SYSCALL_MAX_ARGS - i;
+ else
+ return;
+ }
+
+ for (j = 0; j < n; ++j)
+ regs->areg[reg[i + j]] = args[j];
+}
+
asmlinkage long xtensa_rt_sigreturn(struct pt_regs*);
asmlinkage long xtensa_shmat(int, char __user *, int);
asmlinkage long xtensa_fadvise64_64(int, int,
unsigned long long, unsigned long long);
-/* Should probably move to linux/syscalls.h */
-struct pollfd;
-asmlinkage long sys_pselect6(int n, fd_set __user *inp, fd_set __user *outp,
- fd_set __user *exp, struct timespec __user *tsp,
- void __user *sig);
-asmlinkage long sys_ppoll(struct pollfd __user *ufds, unsigned int nfds,
- struct timespec __user *tsp,
- const sigset_t __user *sigmask,
- size_t sigsetsize);
+#endif
diff --git a/arch/xtensa/include/asm/thread_info.h b/arch/xtensa/include/asm/thread_info.h
index 2bd19ae61e47..f333f10a7650 100644
--- a/arch/xtensa/include/asm/thread_info.h
+++ b/arch/xtensa/include/asm/thread_info.h
@@ -11,6 +11,7 @@
#ifndef _XTENSA_THREAD_INFO_H
#define _XTENSA_THREAD_INFO_H
+#include <linux/stringify.h>
#include <asm/kmem_layout.h>
#define CURRENT_SHIFT KERNEL_STACK_SHIFT
@@ -100,13 +101,12 @@ static inline struct thread_info *current_thread_info(void)
/*
* thread information flags
* - these are process state flags that various assembly files may need to access
- * - pending work-to-be-done flags are in LSW
- * - other flags in MSW
*/
#define TIF_SYSCALL_TRACE 0 /* syscall trace active */
#define TIF_SIGPENDING 1 /* signal pending */
#define TIF_NEED_RESCHED 2 /* rescheduling necessary */
#define TIF_SINGLESTEP 3 /* restore singlestep on return to user mode */
+#define TIF_SYSCALL_TRACEPOINT 4 /* syscall tracepoint instrumentation */
#define TIF_MEMDIE 5 /* is terminating due to OOM killer */
#define TIF_RESTORE_SIGMASK 6 /* restore signal mask in do_signal() */
#define TIF_NOTIFY_RESUME 7 /* callback before returning to user */
@@ -116,9 +116,10 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
#define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP)
+#define _TIF_SYSCALL_TRACEPOINT (1<<TIF_SYSCALL_TRACEPOINT)
-#define _TIF_WORK_MASK 0x0000FFFE /* work to do on interrupt/exception return */
-#define _TIF_ALLWORK_MASK 0x0000FFFF /* work to do on any return to u-space */
+#define _TIF_WORK_MASK (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP | \
+ _TIF_SYSCALL_TRACEPOINT)
/*
* Thread-synchronous status.
diff --git a/arch/xtensa/include/asm/timex.h b/arch/xtensa/include/asm/timex.h
index f9b389d4e973..233ec75e60c6 100644
--- a/arch/xtensa/include/asm/timex.h
+++ b/arch/xtensa/include/asm/timex.h
@@ -10,7 +10,6 @@
#define _XTENSA_TIMEX_H
#include <asm/processor.h>
-#include <linux/stringify.h>
#if XCHAL_NUM_TIMERS > 0 && \
XTENSA_INT_LEVEL(XCHAL_TIMER0_INTERRUPT) <= XCHAL_EXCM_LEVEL
@@ -40,33 +39,24 @@ void local_timer_setup(unsigned cpu);
* Register access.
*/
-#define WSR_CCOUNT(r) asm volatile ("wsr %0, ccount" :: "a" (r))
-#define RSR_CCOUNT(r) asm volatile ("rsr %0, ccount" : "=a" (r))
-#define WSR_CCOMPARE(x,r) asm volatile ("wsr %0,"__stringify(SREG_CCOMPARE)"+"__stringify(x) :: "a"(r))
-#define RSR_CCOMPARE(x,r) asm volatile ("rsr %0,"__stringify(SREG_CCOMPARE)"+"__stringify(x) : "=a"(r))
-
static inline unsigned long get_ccount (void)
{
- unsigned long ccount;
- RSR_CCOUNT(ccount);
- return ccount;
+ return xtensa_get_sr(ccount);
}
static inline void set_ccount (unsigned long ccount)
{
- WSR_CCOUNT(ccount);
+ xtensa_set_sr(ccount, ccount);
}
static inline unsigned long get_linux_timer (void)
{
- unsigned ccompare;
- RSR_CCOMPARE(LINUX_TIMER, ccompare);
- return ccompare;
+ return xtensa_get_sr(SREG_CCOMPARE + LINUX_TIMER);
}
static inline void set_linux_timer (unsigned long ccompare)
{
- WSR_CCOMPARE(LINUX_TIMER, ccompare);
+ xtensa_set_sr(ccompare, SREG_CCOMPARE + LINUX_TIMER);
}
#endif /* _XTENSA_TIMEX_H */
diff --git a/arch/xtensa/include/asm/traps.h b/arch/xtensa/include/asm/traps.h
index f5cd7a7e65e0..f720a57d0a5b 100644
--- a/arch/xtensa/include/asm/traps.h
+++ b/arch/xtensa/include/asm/traps.h
@@ -25,8 +25,6 @@ struct exc_table {
void *fixup;
/* For passing a parameter to fixup */
void *fixup_param;
- /* For fast syscall handler */
- unsigned long syscall_save;
/* Fast user exception handlers */
void *fast_user_handler[EXCCAUSE_N];
/* Fast kernel exception handlers */
diff --git a/arch/xtensa/include/asm/uaccess.h b/arch/xtensa/include/asm/uaccess.h
index f1158b4c629c..d11ef2939652 100644
--- a/arch/xtensa/include/asm/uaccess.h
+++ b/arch/xtensa/include/asm/uaccess.h
@@ -159,10 +159,9 @@ __asm__ __volatile__( \
"2: \n" \
" .section .fixup,\"ax\" \n" \
" .align 4 \n" \
- "4: \n" \
- " .long 2b \n" \
+ " .literal_position \n" \
"5: \n" \
- " l32r %1, 4b \n" \
+ " movi %1, 2b \n" \
" movi %0, %4 \n" \
" jx %1 \n" \
" .previous \n" \
@@ -217,10 +216,9 @@ __asm__ __volatile__( \
"2: \n" \
" .section .fixup,\"ax\" \n" \
" .align 4 \n" \
- "4: \n" \
- " .long 2b \n" \
+ " .literal_position \n" \
"5: \n" \
- " l32r %1, 4b \n" \
+ " movi %1, 2b \n" \
" movi %2, 0 \n" \
" movi %0, %4 \n" \
" jx %1 \n" \
diff --git a/arch/xtensa/include/asm/unistd.h b/arch/xtensa/include/asm/unistd.h
index 574e5520968c..0d34629dafc5 100644
--- a/arch/xtensa/include/asm/unistd.h
+++ b/arch/xtensa/include/asm/unistd.h
@@ -22,4 +22,6 @@
#define __IGNORE_vfork /* use clone */
#define __IGNORE_fadvise64 /* use fadvise64_64 */
+#define NR_syscalls __NR_syscalls
+
#endif /* _XTENSA_UNISTD_H */