Commit f1ba12856b7a7d43e495e216bc91e6bbf7aac383

Authored by Roland McGrath
Committed by Benjamin Herrenschmidt
1 parent 4f72c4279e

powerpc: Add asm/syscall.h with the tracehook entry points

Add asm/syscall.h for powerpc with all the required entry points.
This will allow arch-independent tracing code for system calls.

BenH: Fixed up use of regs->trap to properly mask low bit

Signed-off-by: Roland McGrath <roland@redhat.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>

Showing 2 changed files with 85 additions and 0 deletions Side-by-side Diff

include/asm-powerpc/ptrace.h
... ... @@ -84,6 +84,7 @@
84 84 #ifndef __ASSEMBLY__
85 85  
86 86 #define instruction_pointer(regs) ((regs)->nip)
  87 +#define user_stack_pointer(regs) ((regs)->gpr[1])
87 88 #define regs_return_value(regs) ((regs)->gpr[3])
88 89  
89 90 #ifdef CONFIG_SMP
include/asm-powerpc/syscall.h
  1 +/*
  2 + * Access to user system call parameters and results
  3 + *
  4 + * Copyright (C) 2008 Red Hat, Inc. All rights reserved.
  5 + *
  6 + * This copyrighted material is made available to anyone wishing to use,
  7 + * modify, copy, or redistribute it subject to the terms and conditions
  8 + * of the GNU General Public License v.2.
  9 + *
  10 + * See asm-generic/syscall.h for descriptions of what we must do here.
  11 + */
  12 +
  13 +#ifndef _ASM_SYSCALL_H
  14 +#define _ASM_SYSCALL_H 1
  15 +
  16 +#include <linux/sched.h>
  17 +
  18 +static inline long syscall_get_nr(struct task_struct *task,
  19 + struct pt_regs *regs)
  20 +{
  21 + return TRAP(regs) == 0xc00 ? regs->gpr[0] : -1L;
  22 +}
  23 +
  24 +static inline void syscall_rollback(struct task_struct *task,
  25 + struct pt_regs *regs)
  26 +{
  27 + regs->gpr[3] = regs->orig_gpr3;
  28 +}
  29 +
  30 +static inline long syscall_get_error(struct task_struct *task,
  31 + struct pt_regs *regs)
  32 +{
  33 + return (regs->ccr & 0x1000) ? -regs->gpr[3] : 0;
  34 +}
  35 +
  36 +static inline long syscall_get_return_value(struct task_struct *task,
  37 + struct pt_regs *regs)
  38 +{
  39 + return regs->gpr[3];
  40 +}
  41 +
  42 +static inline void syscall_set_return_value(struct task_struct *task,
  43 + struct pt_regs *regs,
  44 + int error, long val)
  45 +{
  46 + if (error) {
  47 + regs->ccr |= 0x1000L;
  48 + regs->gpr[3] = -error;
  49 + } else {
  50 + regs->ccr &= ~0x1000L;
  51 + regs->gpr[3] = val;
  52 + }
  53 +}
  54 +
  55 +static inline void syscall_get_arguments(struct task_struct *task,
  56 + struct pt_regs *regs,
  57 + unsigned int i, unsigned int n,
  58 + unsigned long *args)
  59 +{
  60 + BUG_ON(i + n > 6);
  61 +#ifdef CONFIG_PPC64
  62 + if (test_tsk_thread_flag(task, TIF_32BIT)) {
  63 + /*
  64 + * Zero-extend 32-bit argument values. The high bits are
  65 + * garbage ignored by the actual syscall dispatch.
  66 + */
  67 + while (n-- > 0)
  68 + args[n] = (u32) regs->gpr[3 + i + n];
  69 + return;
  70 + }
  71 +#endif
  72 + memcpy(args, &regs->gpr[3 + i], n * sizeof(args[0]));
  73 +}
  74 +
  75 +static inline void syscall_set_arguments(struct task_struct *task,
  76 + struct pt_regs *regs,
  77 + unsigned int i, unsigned int n,
  78 + const unsigned long *args)
  79 +{
  80 + BUG_ON(i + n > 6);
  81 + memcpy(&regs->gpr[3 + i], args, n * sizeof(args[0]));
  82 +}
  83 +
  84 +#endif /* _ASM_SYSCALL_H */