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:
@@ -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,
|
||||
|
@@ -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)
|
||||
{
|
||||
|
@@ -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__)) */
|
||||
|
@@ -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))
|
||||
|
||||
|
@@ -4,6 +4,7 @@
|
||||
#ifdef CONFIG_NUMA
|
||||
|
||||
#include <asm/mmzone.h>
|
||||
#include <asm/cpudata.h>
|
||||
|
||||
static inline int cpu_to_node(int cpu)
|
||||
{
|
||||
|
@@ -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
|
||||
|
59
arch/sparc/include/asm/uprobes.h
Normal file
59
arch/sparc/include/asm/uprobes.h
Normal 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 */
|
Reference in New Issue
Block a user