Skip to content

Commit

Permalink
sparc64: Implement HAVE_CONTEXT_TRACKING
Browse files Browse the repository at this point in the history
Mark the places when the system are in user or are in kernel.
This is used to make full dynticks system (tickless) --
CONFIG_NO_HZ_FULL dependence.

Signed-off-by: Kirill Tkhai <tkhai@yandex.ru>
CC: David Miller <davem@davemloft.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Kirill Tkhai authored and David S. Miller committed Nov 14, 2013
1 parent 1a36265 commit 812cb83
Show file tree
Hide file tree
Showing 14 changed files with 137 additions and 39 deletions.
1 change: 1 addition & 0 deletions arch/sparc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ config SPARC64
select HAVE_DYNAMIC_FTRACE
select HAVE_FTRACE_MCOUNT_RECORD
select HAVE_SYSCALL_TRACEPOINTS
select HAVE_CONTEXT_TRACKING
select HAVE_DEBUG_KMEMLEAK
select RTC_DRV_CMOS
select RTC_DRV_BQ4802
Expand Down
3 changes: 2 additions & 1 deletion arch/sparc/include/asm/thread_info_64.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ register struct thread_info *current_thread_info_reg asm("g6");
#define TIF_UNALIGNED 5 /* allowed to do unaligned accesses */
/* flag bit 6 is available */
#define TIF_32BIT 7 /* 32-bit binary */
/* flag bit 8 is available */
#define TIF_NOHZ 8 /* in adaptive nohz mode */
#define TIF_SECCOMP 9 /* secure computing */
#define TIF_SYSCALL_AUDIT 10 /* syscall auditing active */
#define TIF_SYSCALL_TRACEPOINT 11 /* syscall tracepoint instrumentation */
Expand All @@ -210,6 +210,7 @@ register struct thread_info *current_thread_info_reg asm("g6");
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
#define _TIF_UNALIGNED (1<<TIF_UNALIGNED)
#define _TIF_32BIT (1<<TIF_32BIT)
#define _TIF_NOHZ (1<<TIF_NOHZ)
#define _TIF_SECCOMP (1<<TIF_SECCOMP)
#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
#define _TIF_SYSCALL_TRACEPOINT (1<<TIF_SYSCALL_TRACEPOINT)
Expand Down
1 change: 0 additions & 1 deletion arch/sparc/kernel/entry.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ extern asmlinkage void syscall_trace_leave(struct pt_regs *regs);

extern void bad_trap_tl1(struct pt_regs *regs, long lvl);

extern void do_fpe_common(struct pt_regs *regs);
extern void do_fpieee(struct pt_regs *regs);
extern void do_fpother(struct pt_regs *regs);
extern void do_tof(struct pt_regs *regs);
Expand Down
5 changes: 4 additions & 1 deletion arch/sparc/kernel/kgdb_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -159,18 +159,21 @@ int kgdb_arch_handle_exception(int e_vector, int signo, int err_code,

asmlinkage void kgdb_trap(unsigned long trap_level, struct pt_regs *regs)
{
enum ctx_state prev_state = exception_enter();
unsigned long flags;

if (user_mode(regs)) {
bad_trap(regs, trap_level);
return;
goto out;
}

flushw_all();

local_irq_save(flags);
kgdb_handle_exception(0x172, SIGTRAP, 0, regs);
local_irq_restore(flags);
out:
exception_exit(prev_state);
}

int kgdb_arch_init(void)
Expand Down
7 changes: 6 additions & 1 deletion arch/sparc/kernel/kprobes.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <linux/module.h>
#include <linux/kdebug.h>
#include <linux/slab.h>
#include <linux/context_tracking.h>
#include <asm/signal.h>
#include <asm/cacheflush.h>
#include <asm/uaccess.h>
Expand Down Expand Up @@ -418,12 +419,14 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
asmlinkage void __kprobes kprobe_trap(unsigned long trap_level,
struct pt_regs *regs)
{
enum ctx_state prev_state = exception_enter();

BUG_ON(trap_level != 0x170 && trap_level != 0x171);

if (user_mode(regs)) {
local_irq_enable();
bad_trap(regs, trap_level);
return;
goto out;
}

/* trap_level == 0x170 --> ta 0x70
Expand All @@ -433,6 +436,8 @@ asmlinkage void __kprobes kprobe_trap(unsigned long trap_level,
(trap_level == 0x170) ? "debug" : "debug_2",
regs, 0, trap_level, SIGTRAP) != NOTIFY_STOP)
bad_trap(regs, trap_level);
out:
exception_exit(prev_state);
}

/* Jprobes support. */
Expand Down
2 changes: 2 additions & 0 deletions arch/sparc/kernel/process_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include <linux/elfcore.h>
#include <linux/sysrq.h>
#include <linux/nmi.h>
#include <linux/context_tracking.h>

#include <asm/uaccess.h>
#include <asm/page.h>
Expand Down Expand Up @@ -557,6 +558,7 @@ void fault_in_user_windows(void)

barf:
set_thread_wsaved(window + 1);
user_exit();
do_exit(SIGILL);
}

Expand Down
10 changes: 10 additions & 0 deletions arch/sparc/kernel/ptrace_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <trace/syscall.h>
#include <linux/compat.h>
#include <linux/elf.h>
#include <linux/context_tracking.h>

#include <asm/asi.h>
#include <asm/pgtable.h>
Expand Down Expand Up @@ -1066,6 +1067,9 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs)
/* do the secure computing check first */
secure_computing_strict(regs->u_regs[UREG_G1]);

if (test_thread_flag(TIF_NOHZ))
user_exit();

if (test_thread_flag(TIF_SYSCALL_TRACE))
ret = tracehook_report_syscall_entry(regs);

Expand All @@ -1086,11 +1090,17 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs)

asmlinkage void syscall_trace_leave(struct pt_regs *regs)
{
if (test_thread_flag(TIF_NOHZ))
user_exit();

audit_syscall_exit(regs);

if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
trace_sys_exit(regs, regs->u_regs[UREG_I0]);

if (test_thread_flag(TIF_SYSCALL_TRACE))
tracehook_report_syscall_exit(regs, 0);

if (test_thread_flag(TIF_NOHZ))
user_enter();
}
8 changes: 7 additions & 1 deletion arch/sparc/kernel/rtrap_64.S
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,16 @@
#define RTRAP_PSTATE_IRQOFF (PSTATE_TSO|PSTATE_PEF|PSTATE_PRIV)
#define RTRAP_PSTATE_AG_IRQOFF (PSTATE_TSO|PSTATE_PEF|PSTATE_PRIV|PSTATE_AG)

#ifdef CONFIG_CONTEXT_TRACKING
# define SCHEDULE_USER schedule_user
#else
# define SCHEDULE_USER schedule
#endif

.text
.align 32
__handle_preemption:
call schedule
call SCHEDULE_USER
wrpr %g0, RTRAP_PSTATE, %pstate
ba,pt %xcc, __handle_preemption_continue
wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate
Expand Down
13 changes: 11 additions & 2 deletions arch/sparc/kernel/signal_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <linux/tty.h>
#include <linux/binfmts.h>
#include <linux/bitops.h>
#include <linux/context_tracking.h>

#include <asm/uaccess.h>
#include <asm/ptrace.h>
Expand All @@ -43,6 +44,7 @@ asmlinkage void sparc64_set_context(struct pt_regs *regs)
{
struct ucontext __user *ucp = (struct ucontext __user *)
regs->u_regs[UREG_I0];
enum ctx_state prev_state = exception_enter();
mc_gregset_t __user *grp;
unsigned long pc, npc, tstate;
unsigned long fp, i7;
Expand Down Expand Up @@ -129,16 +131,19 @@ asmlinkage void sparc64_set_context(struct pt_regs *regs)
}
if (err)
goto do_sigsegv;

out:
exception_exit(prev_state);
return;
do_sigsegv:
force_sig(SIGSEGV, current);
goto out;
}

asmlinkage void sparc64_get_context(struct pt_regs *regs)
{
struct ucontext __user *ucp = (struct ucontext __user *)
regs->u_regs[UREG_I0];
enum ctx_state prev_state = exception_enter();
mc_gregset_t __user *grp;
mcontext_t __user *mcp;
unsigned long fp, i7;
Expand Down Expand Up @@ -220,10 +225,12 @@ asmlinkage void sparc64_get_context(struct pt_regs *regs)
}
if (err)
goto do_sigsegv;

out:
exception_exit(prev_state);
return;
do_sigsegv:
force_sig(SIGSEGV, current);
goto out;
}

struct rt_signal_frame {
Expand Down Expand Up @@ -528,11 +535,13 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)

void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, unsigned long thread_info_flags)
{
user_exit();
if (thread_info_flags & _TIF_SIGPENDING)
do_signal(regs, orig_i0);
if (thread_info_flags & _TIF_NOTIFY_RESUME) {
clear_thread_flag(TIF_NOTIFY_RESUME);
tracehook_notify_resume(regs);
}
user_enter();
}

3 changes: 3 additions & 0 deletions arch/sparc/kernel/sys_sparc_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <linux/personality.h>
#include <linux/random.h>
#include <linux/export.h>
#include <linux/context_tracking.h>

#include <asm/uaccess.h>
#include <asm/utrap.h>
Expand Down Expand Up @@ -496,6 +497,7 @@ asmlinkage unsigned long c_sys_nis_syscall(struct pt_regs *regs)

asmlinkage void sparc_breakpoint(struct pt_regs *regs)
{
enum ctx_state prev_state = exception_enter();
siginfo_t info;

if (test_thread_flag(TIF_32BIT)) {
Expand All @@ -514,6 +516,7 @@ asmlinkage void sparc_breakpoint(struct pt_regs *regs)
#ifdef DEBUG_SPARC_BREAKPOINT
printk ("TRAP: Returning to space: PC=%lx nPC=%lx\n", regs->tpc, regs->tnpc);
#endif
exception_exit(prev_state);
}

extern void check_pending(int signum);
Expand Down
8 changes: 4 additions & 4 deletions arch/sparc/kernel/syscalls.S
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ sys32_rt_sigreturn:
#endif
.align 32
1: ldx [%g6 + TI_FLAGS], %l5
andcc %l5, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %g0
andcc %l5, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT|_TIF_NOHZ), %g0
be,pt %icc, rtrap
nop
call syscall_trace_leave
Expand Down Expand Up @@ -184,7 +184,7 @@ linux_sparc_syscall32:

srl %i3, 0, %o3 ! IEU0
srl %i2, 0, %o2 ! IEU0 Group
andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %g0
andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT|_TIF_NOHZ), %g0
bne,pn %icc, linux_syscall_trace32 ! CTI
mov %i0, %l5 ! IEU1
5: call %l7 ! CTI Group brk forced
Expand All @@ -207,7 +207,7 @@ linux_sparc_syscall:

mov %i3, %o3 ! IEU1
mov %i4, %o4 ! IEU0 Group
andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %g0
andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT|_TIF_NOHZ), %g0
bne,pn %icc, linux_syscall_trace ! CTI Group
mov %i0, %l5 ! IEU0
2: call %l7 ! CTI Group brk forced
Expand All @@ -223,7 +223,7 @@ ret_sys_call:

cmp %o0, -ERESTART_RESTARTBLOCK
bgeu,pn %xcc, 1f
andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %g0
andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT|_TIF_NOHZ), %g0
ldx [%sp + PTREGS_OFF + PT_V9_TNPC], %l1 ! pc = npc

2:
Expand Down
Loading

0 comments on commit 812cb83

Please sign in to comment.