Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc

Pull sparc updates from David Miller:
 "Just a bunch of small cleanups and fixes here, and support for user
  probes from Allen Pais"

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc:
  sparc: fix a building error reported by kbuild
  sparc64: fix typo in pgd_clear()
  sparc64: restore irq in error paths in iommu
  sparc: leon: Fix a retry loop in leon_init_timers()
  sparc64: make string buffers large enough
  sparc64: move dereference after check for NULL
  sparc: kernel: use builtin_platform_driver
  sparc64:Support User Probes for sparc
This commit is contained in:
Linus Torvalds
2016-12-12 08:18:41 -08:00
20 changed files with 537 additions and 44 deletions

View File

@@ -10,6 +10,8 @@ enum die_val {
DIE_OOPS = 1,
DIE_DEBUG, /* ta 0x70 */
DIE_DEBUG_2, /* ta 0x71 */
DIE_BPT, /* ta 0x73 */
DIE_SSTEP, /* ta 0x74 */
DIE_DIE,
DIE_TRAP,
DIE_TRAP_TL1,

View File

@@ -826,7 +826,7 @@ static inline unsigned long __pmd_page(pmd_t pmd)
#define pgd_page_vaddr(pgd) \
((unsigned long) __va(pgd_val(pgd)))
#define pgd_present(pgd) (pgd_val(pgd) != 0U)
#define pgd_clear(pgdp) (pgd_val(*(pgd)) = 0UL)
#define pgd_clear(pgdp) (pgd_val(*(pgdp)) = 0UL)
static inline unsigned long pud_large(pud_t pud)
{

View File

@@ -61,7 +61,10 @@ extern union global_cpu_snapshot global_cpu_snapshot[NR_CPUS];
#define force_successful_syscall_return() set_thread_noerror(1)
#define user_mode(regs) (!((regs)->tstate & TSTATE_PRIV))
#define instruction_pointer(regs) ((regs)->tpc)
#define instruction_pointer_set(regs, val) ((regs)->tpc = (val))
#define instruction_pointer_set(regs, val) do { \
(regs)->tpc = (val); \
(regs)->tnpc = (val)+4; \
} while (0)
#define user_stack_pointer(regs) ((regs)->u_regs[UREG_FP])
static inline int is_syscall_success(struct pt_regs *regs)
{
@@ -77,6 +80,36 @@ unsigned long profile_pc(struct pt_regs *);
#else
#define profile_pc(regs) instruction_pointer(regs)
#endif
#define MAX_REG_OFFSET (offsetof(struct pt_regs, magic))
extern int regs_query_register_offset(const char *name);
/**
* regs_get_register() - get register value from its offset
* @regs: pt_regs from which register value is gotten
* @offset: offset number of the register.
*
* regs_get_register returns the value of a register whose
* offset from @regs. The @offset is the offset of the register
* in struct pt_regs. If @offset is bigger than MAX_REG_OFFSET,
* this returns 0.
*/
static inline unsigned long regs_get_register(struct pt_regs *regs,
unsigned long offset)
{
if (unlikely(offset >= MAX_REG_OFFSET))
return 0;
if (offset == PT_V9_Y)
return *(unsigned int *)((unsigned long)regs + offset);
return *(unsigned long *)((unsigned long)regs + offset);
}
/* Valid only for Kernel mode traps. */
static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
{
return regs->u_regs[UREG_I6];
}
#else /* __ASSEMBLY__ */
#endif /* __ASSEMBLY__ */
#else /* (defined(__sparc__) && defined(__arch64__)) */

View File

@@ -180,7 +180,7 @@ register struct thread_info *current_thread_info_reg asm("g6");
#define TIF_NEED_RESCHED 3 /* rescheduling necessary */
/* flag bit 4 is available */
#define TIF_UNALIGNED 5 /* allowed to do unaligned accesses */
/* flag bit 6 is available */
#define TIF_UPROBE 6 /* breakpointed or singlestepped */
#define TIF_32BIT 7 /* 32-bit binary */
#define TIF_NOHZ 8 /* in adaptive nohz mode */
#define TIF_SECCOMP 9 /* secure computing */
@@ -199,6 +199,7 @@ register struct thread_info *current_thread_info_reg asm("g6");
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
#define _TIF_UNALIGNED (1<<TIF_UNALIGNED)
#define _TIF_UPROBE (1<<TIF_UPROBE)
#define _TIF_32BIT (1<<TIF_32BIT)
#define _TIF_NOHZ (1<<TIF_NOHZ)
#define _TIF_SECCOMP (1<<TIF_SECCOMP)
@@ -209,7 +210,8 @@ register struct thread_info *current_thread_info_reg asm("g6");
#define _TIF_USER_WORK_MASK ((0xff << TI_FLAG_WSAVED_SHIFT) | \
_TIF_DO_NOTIFY_RESUME_MASK | \
_TIF_NEED_RESCHED)
#define _TIF_DO_NOTIFY_RESUME_MASK (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING)
#define _TIF_DO_NOTIFY_RESUME_MASK (_TIF_NOTIFY_RESUME | \
_TIF_SIGPENDING | _TIF_UPROBE)
#define is_32bit_task() (test_thread_flag(TIF_32BIT))

View File

@@ -4,6 +4,7 @@
#ifdef CONFIG_NUMA
#include <asm/mmzone.h>
#include <asm/cpudata.h>
static inline int cpu_to_node(int cpu)
{

View File

@@ -186,6 +186,12 @@
#define KPROBES_TRAP(lvl) TRAP_ARG(bad_trap, lvl)
#endif
#ifdef CONFIG_UPROBES
#define UPROBES_TRAP(lvl) TRAP_ARG(uprobe_trap, lvl)
#else
#define UPROBES_TRAP(lvl) TRAP_ARG(bad_trap, lvl)
#endif
#ifdef CONFIG_KGDB
#define KGDB_TRAP(lvl) TRAP_IRQ(kgdb_trap, lvl)
#else

View File

@@ -0,0 +1,59 @@
#ifndef _ASM_UPROBES_H
#define _ASM_UPROBES_H
/*
* User-space Probes (UProbes) for sparc
*
* Copyright (C) 2013 Oracle, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Authors:
* Jose E. Marchesi <jose.marchesi@oracle.com>
* Eric Saint Etienne <eric.saint.etienne@oracle.com>
*/
typedef u32 uprobe_opcode_t;
#define MAX_UINSN_BYTES 4
#define UPROBE_XOL_SLOT_BYTES (MAX_UINSN_BYTES * 2)
#define UPROBE_SWBP_INSN_SIZE 4
#define UPROBE_SWBP_INSN 0x91d02073 /* ta 0x73 */
#define UPROBE_STP_INSN 0x91d02074 /* ta 0x74 */
#define ANNUL_BIT (1 << 29)
struct arch_uprobe {
union {
u8 insn[MAX_UINSN_BYTES];
u32 ixol;
};
};
struct arch_uprobe_task {
u32 saved_tpc;
u32 saved_tnpc;
};
struct task_struct;
struct notifier_block;
extern int arch_uprobe_analyze_insn(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long addr);
extern int arch_uprobe_pre_xol(struct arch_uprobe *aup, struct pt_regs *regs);
extern int arch_uprobe_post_xol(struct arch_uprobe *aup, struct pt_regs *regs);
extern bool arch_uprobe_xol_was_trapped(struct task_struct *tsk);
extern int arch_uprobe_exception_notify(struct notifier_block *self, unsigned long val, void *data);
extern void arch_uprobe_abort_xol(struct arch_uprobe *aup, struct pt_regs *regs);
#endif /* _ASM_UPROBES_H */