Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.8.
  1/* syscall parameter access functions
  2 *
  3 * Copyright (C) 2009 Red Hat, Inc. All Rights Reserved.
  4 * Written by David Howells (dhowells@redhat.com)
  5 *
  6 * This program is free software; you can redistribute it and/or
  7 * modify it under the terms of the GNU General Public Licence
  8 * as published by the Free Software Foundation; either version
  9 * 2 of the Licence, or (at your option) any later version.
 10 */
 11
 12#ifndef _ASM_SYSCALL_H
 13#define _ASM_SYSCALL_H
 14
 15#include <linux/err.h>
 16#include <asm/ptrace.h>
 17
 18/*
 19 * Get the system call number or -1
 20 */
 21static inline long syscall_get_nr(struct task_struct *task,
 22				  struct pt_regs *regs)
 23{
 24	return regs->syscallno;
 25}
 26
 27/*
 28 * Restore the clobbered GR8 register
 29 * (1st syscall arg was overwritten with syscall return or error)
 30 */
 31static inline void syscall_rollback(struct task_struct *task,
 32				    struct pt_regs *regs)
 33{
 34	regs->gr8 = regs->orig_gr8;
 35}
 36
 37/*
 38 * See if the syscall return value is an error, returning it if it is and 0 if
 39 * not
 40 */
 41static inline long syscall_get_error(struct task_struct *task,
 42				     struct pt_regs *regs)
 43{
 44	return IS_ERR_VALUE(regs->gr8) ? regs->gr8 : 0;
 45}
 46
 47/*
 48 * Get the syscall return value
 49 */
 50static inline long syscall_get_return_value(struct task_struct *task,
 51					    struct pt_regs *regs)
 52{
 53	return regs->gr8;
 54}
 55
 56/*
 57 * Set the syscall return value
 58 */
 59static inline void syscall_set_return_value(struct task_struct *task,
 60					    struct pt_regs *regs,
 61					    int error, long val)
 62{
 63	if (error)
 64		regs->gr8 = -error;
 65	else
 66		regs->gr8 = val;
 67}
 68
 69/*
 70 * Retrieve the system call arguments
 71 */
 72static inline void syscall_get_arguments(struct task_struct *task,
 73					 struct pt_regs *regs,
 74					 unsigned int i, unsigned int n,
 75					 unsigned long *args)
 76{
 77	/*
 78	 * Do this simply for now. If we need to start supporting
 79	 * fetching arguments from arbitrary indices, this will need some
 80	 * extra logic. Presently there are no in-tree users that depend
 81	 * on this behaviour.
 82	 */
 83	BUG_ON(i);
 84
 85	/* Argument pattern is: GR8, GR9, GR10, GR11, GR12, GR13 */
 86	switch (n) {
 87	case 6: args[5] = regs->gr13;
 88	case 5: args[4] = regs->gr12;
 89	case 4: args[3] = regs->gr11;
 90	case 3: args[2] = regs->gr10;
 91	case 2: args[1] = regs->gr9;
 92	case 1:	args[0] = regs->gr8;
 93		break;
 94	default:
 95		BUG();
 96	}
 97}
 98
 99/*
100 * Alter the system call arguments
101 */
102static inline void syscall_set_arguments(struct task_struct *task,
103					 struct pt_regs *regs,
104					 unsigned int i, unsigned int n,
105					 const unsigned long *args)
106{
107	/* Same note as above applies */
108	BUG_ON(i);
109
110	switch (n) {
111	case 6: regs->gr13 = args[5];
112	case 5: regs->gr12 = args[4];
113	case 4: regs->gr11 = args[3];
114	case 3: regs->gr10 = args[2];
115	case 2: regs->gr9  = args[1];
116	case 1: regs->gr8  = args[0];
117		break;
118	default:
119		BUG();
120	}
121}
122
123#endif /* _ASM_SYSCALL_H */