Skip to content

Commit 9d57940

Browse files
author
Fox Snowpatch
committed
1 parent 56e2adc commit 9d57940

File tree

9 files changed

+28
-147
lines changed

9 files changed

+28
-147
lines changed

arch/powerpc/Kconfig

+1
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ config PPC
204204
select GENERIC_IRQ_SHOW_LEVEL
205205
select GENERIC_PCI_IOMAP if PCI
206206
select GENERIC_PTDUMP
207+
select GENERIC_ENTRY
207208
select GENERIC_SMP_IDLE_THREAD
208209
select GENERIC_TIME_VSYSCALL
209210
select GENERIC_VDSO_TIME_NS

arch/powerpc/include/asm/hw_irq.h

+5
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,11 @@ static inline bool arch_irqs_disabled(void)
216216
return arch_irqs_disabled_flags(arch_local_save_flags());
217217
}
218218

219+
/*common entry*/
220+
static __always_inline bool regs_irqs_disabled(struct pt_regs *regs)
221+
{
222+
return arch_irqs_disabled();
223+
}
219224
static inline void set_pmi_irq_pending(void)
220225
{
221226
/*

arch/powerpc/include/asm/processor.h

+6
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,12 @@ int validate_sp(unsigned long sp, struct task_struct *p);
394394
int validate_sp_size(unsigned long sp, struct task_struct *p,
395395
unsigned long nbytes);
396396

397+
/*for common entry*/
398+
static __always_inline bool on_thread_stack(void)
399+
{
400+
return validate_sp(current_stack_pointer, current);
401+
}
402+
397403
/*
398404
* Prefetch macros.
399405
*/

arch/powerpc/include/asm/syscall.h

+5
Original file line numberDiff line numberDiff line change
@@ -119,4 +119,9 @@ static inline int syscall_get_arch(struct task_struct *task)
119119
else
120120
return AUDIT_ARCH_PPC64;
121121
}
122+
123+
static inline bool arch_syscall_is_vdso_sigreturn(struct pt_regs *regs)
124+
{
125+
return false;
126+
}
122127
#endif /* _ASM_SYSCALL_H */

arch/powerpc/include/asm/thread_info.h

+1
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ struct thread_info {
5858
unsigned int cpu;
5959
#endif
6060
unsigned long local_flags; /* private flags for thread */
61+
unsigned long syscall_work;
6162
#ifdef CONFIG_LIVEPATCH_64
6263
unsigned long *livepatch_sp;
6364
#endif

arch/powerpc/kernel/interrupt.c

-5
Original file line numberDiff line numberDiff line change
@@ -294,11 +294,6 @@ notrace unsigned long syscall_exit_prepare(unsigned long r3,
294294
regs->gpr[3] = r3;
295295
}
296296

297-
if (unlikely(ti_flags & _TIF_SYSCALL_DOTRACE)) {
298-
do_syscall_trace_leave(regs);
299-
ret |= _TIF_RESTOREALL;
300-
}
301-
302297
local_irq_disable();
303298
ret = interrupt_exit_user_prepare_main(ret, regs);
304299

arch/powerpc/kernel/ptrace/ptrace.c

-141
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,6 @@
2121
#include <asm/switch_to.h>
2222
#include <asm/debug.h>
2323

24-
#define CREATE_TRACE_POINTS
25-
#include <trace/events/syscalls.h>
26-
2724
#include "ptrace-decl.h"
2825

2926
/*
@@ -195,144 +192,6 @@ long arch_ptrace(struct task_struct *child, long request,
195192
return ret;
196193
}
197194

198-
#ifdef CONFIG_SECCOMP
199-
static int do_seccomp(struct pt_regs *regs)
200-
{
201-
if (!test_thread_flag(TIF_SECCOMP))
202-
return 0;
203-
204-
/*
205-
* The ABI we present to seccomp tracers is that r3 contains
206-
* the syscall return value and orig_gpr3 contains the first
207-
* syscall parameter. This is different to the ptrace ABI where
208-
* both r3 and orig_gpr3 contain the first syscall parameter.
209-
*/
210-
regs->gpr[3] = -ENOSYS;
211-
212-
/*
213-
* We use the __ version here because we have already checked
214-
* TIF_SECCOMP. If this fails, there is nothing left to do, we
215-
* have already loaded -ENOSYS into r3, or seccomp has put
216-
* something else in r3 (via SECCOMP_RET_ERRNO/TRACE).
217-
*/
218-
if (__secure_computing(NULL))
219-
return -1;
220-
221-
/*
222-
* The syscall was allowed by seccomp, restore the register
223-
* state to what audit expects.
224-
* Note that we use orig_gpr3, which means a seccomp tracer can
225-
* modify the first syscall parameter (in orig_gpr3) and also
226-
* allow the syscall to proceed.
227-
*/
228-
regs->gpr[3] = regs->orig_gpr3;
229-
230-
return 0;
231-
}
232-
#else
233-
static inline int do_seccomp(struct pt_regs *regs) { return 0; }
234-
#endif /* CONFIG_SECCOMP */
235-
236-
/**
237-
* do_syscall_trace_enter() - Do syscall tracing on kernel entry.
238-
* @regs: the pt_regs of the task to trace (current)
239-
*
240-
* Performs various types of tracing on syscall entry. This includes seccomp,
241-
* ptrace, syscall tracepoints and audit.
242-
*
243-
* The pt_regs are potentially visible to userspace via ptrace, so their
244-
* contents is ABI.
245-
*
246-
* One or more of the tracers may modify the contents of pt_regs, in particular
247-
* to modify arguments or even the syscall number itself.
248-
*
249-
* It's also possible that a tracer can choose to reject the system call. In
250-
* that case this function will return an illegal syscall number, and will put
251-
* an appropriate return value in regs->r3.
252-
*
253-
* Return: the (possibly changed) syscall number.
254-
*/
255-
long do_syscall_trace_enter(struct pt_regs *regs)
256-
{
257-
u32 flags;
258-
259-
flags = read_thread_flags() & (_TIF_SYSCALL_EMU | _TIF_SYSCALL_TRACE);
260-
261-
if (flags) {
262-
int rc = ptrace_report_syscall_entry(regs);
263-
264-
if (unlikely(flags & _TIF_SYSCALL_EMU)) {
265-
/*
266-
* A nonzero return code from
267-
* ptrace_report_syscall_entry() tells us to prevent
268-
* the syscall execution, but we are not going to
269-
* execute it anyway.
270-
*
271-
* Returning -1 will skip the syscall execution. We want
272-
* to avoid clobbering any registers, so we don't goto
273-
* the skip label below.
274-
*/
275-
return -1;
276-
}
277-
278-
if (rc) {
279-
/*
280-
* The tracer decided to abort the syscall. Note that
281-
* the tracer may also just change regs->gpr[0] to an
282-
* invalid syscall number, that is handled below on the
283-
* exit path.
284-
*/
285-
goto skip;
286-
}
287-
}
288-
289-
/* Run seccomp after ptrace; allow it to set gpr[3]. */
290-
if (do_seccomp(regs))
291-
return -1;
292-
293-
/* Avoid trace and audit when syscall is invalid. */
294-
if (regs->gpr[0] >= NR_syscalls)
295-
goto skip;
296-
297-
if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
298-
trace_sys_enter(regs, regs->gpr[0]);
299-
300-
if (!is_32bit_task())
301-
audit_syscall_entry(regs->gpr[0], regs->gpr[3], regs->gpr[4],
302-
regs->gpr[5], regs->gpr[6]);
303-
else
304-
audit_syscall_entry(regs->gpr[0],
305-
regs->gpr[3] & 0xffffffff,
306-
regs->gpr[4] & 0xffffffff,
307-
regs->gpr[5] & 0xffffffff,
308-
regs->gpr[6] & 0xffffffff);
309-
310-
/* Return the possibly modified but valid syscall number */
311-
return regs->gpr[0];
312-
313-
skip:
314-
/*
315-
* If we are aborting explicitly, or if the syscall number is
316-
* now invalid, set the return value to -ENOSYS.
317-
*/
318-
regs->gpr[3] = -ENOSYS;
319-
return -1;
320-
}
321-
322-
void do_syscall_trace_leave(struct pt_regs *regs)
323-
{
324-
int step;
325-
326-
audit_syscall_exit(regs);
327-
328-
if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
329-
trace_sys_exit(regs, regs->result);
330-
331-
step = test_thread_flag(TIF_SINGLESTEP);
332-
if (step || test_thread_flag(TIF_SYSCALL_TRACE))
333-
ptrace_report_syscall_exit(regs, step);
334-
}
335-
336195
void __init pt_regs_check(void);
337196

338197
/*

arch/powerpc/kernel/syscall.c

+5-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <linux/compat.h>
44
#include <linux/context_tracking.h>
55
#include <linux/randomize_kstack.h>
6+
#include <linux/entry-common.h>
67

78
#include <asm/interrupt.h>
89
#include <asm/kup.h>
@@ -131,7 +132,7 @@ notrace long system_call_exception(struct pt_regs *regs, unsigned long r0)
131132
* and the test against NR_syscalls will fail and the return
132133
* value to be used is in regs->gpr[3].
133134
*/
134-
r0 = do_syscall_trace_enter(regs);
135+
syscall_enter_from_user_mode(regs, r0);
135136
if (unlikely(r0 >= NR_syscalls))
136137
return regs->gpr[3];
137138

@@ -185,5 +186,8 @@ notrace long system_call_exception(struct pt_regs *regs, unsigned long r0)
185186
*/
186187
choose_random_kstack_offset(mftb());
187188

189+
/*common entry*/
190+
syscall_exit_to_user_mode(regs);
191+
188192
return ret;
189193
}

arch/powerpc/mm/fault.c

+5
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <linux/mman.h>
2424
#include <linux/mm.h>
2525
#include <linux/interrupt.h>
26+
#include <linux/entry-common.h>
2627
#include <linux/highmem.h>
2728
#include <linux/extable.h>
2829
#include <linux/kprobes.h>
@@ -578,15 +579,19 @@ NOKPROBE_SYMBOL(___do_page_fault);
578579
static __always_inline void __do_page_fault(struct pt_regs *regs)
579580
{
580581
long err;
582+
irqentry_state_t state = irqentry_enter(regs);
581583

582584
err = ___do_page_fault(regs, regs->dar, regs->dsisr);
583585
if (unlikely(err))
584586
bad_page_fault(regs, err);
587+
irqentry_exit(regs, state);
585588
}
586589

587590
DEFINE_INTERRUPT_HANDLER(do_page_fault)
588591
{
592+
irqentry_state_t state = irqentry_enter(regs);
589593
__do_page_fault(regs);
594+
irqentry_exit(regs, state);
590595
}
591596

592597
#ifdef CONFIG_PPC_BOOK3S_64

0 commit comments

Comments
 (0)