Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/unicore32/kernel/sys.c
10817 views
1
/*
2
* linux/arch/unicore32/kernel/sys.c
3
*
4
* Code specific to PKUnity SoC and UniCore ISA
5
*
6
* Copyright (C) 2001-2010 GUAN Xue-tao
7
*
8
* This program is free software; you can redistribute it and/or modify
9
* it under the terms of the GNU General Public License version 2 as
10
* published by the Free Software Foundation.
11
*/
12
#include <linux/module.h>
13
#include <linux/errno.h>
14
#include <linux/sched.h>
15
#include <linux/slab.h>
16
#include <linux/mm.h>
17
#include <linux/sem.h>
18
#include <linux/msg.h>
19
#include <linux/shm.h>
20
#include <linux/stat.h>
21
#include <linux/syscalls.h>
22
#include <linux/mman.h>
23
#include <linux/fs.h>
24
#include <linux/file.h>
25
#include <linux/ipc.h>
26
#include <linux/uaccess.h>
27
28
#include <asm/syscalls.h>
29
#include <asm/cacheflush.h>
30
31
/* Clone a task - this clones the calling program thread.
32
* This is called indirectly via a small wrapper
33
*/
34
asmlinkage long __sys_clone(unsigned long clone_flags, unsigned long newsp,
35
void __user *parent_tid, void __user *child_tid,
36
struct pt_regs *regs)
37
{
38
if (!newsp)
39
newsp = regs->UCreg_sp;
40
41
return do_fork(clone_flags, newsp, regs, 0,
42
parent_tid, child_tid);
43
}
44
45
/* sys_execve() executes a new program.
46
* This is called indirectly via a small wrapper
47
*/
48
asmlinkage long __sys_execve(const char __user *filename,
49
const char __user *const __user *argv,
50
const char __user *const __user *envp,
51
struct pt_regs *regs)
52
{
53
int error;
54
char *fn;
55
56
fn = getname(filename);
57
error = PTR_ERR(fn);
58
if (IS_ERR(fn))
59
goto out;
60
error = do_execve(fn, argv, envp, regs);
61
putname(fn);
62
out:
63
return error;
64
}
65
66
int kernel_execve(const char *filename,
67
const char *const argv[],
68
const char *const envp[])
69
{
70
struct pt_regs regs;
71
int ret;
72
73
memset(&regs, 0, sizeof(struct pt_regs));
74
ret = do_execve(filename,
75
(const char __user *const __user *)argv,
76
(const char __user *const __user *)envp, &regs);
77
if (ret < 0)
78
goto out;
79
80
/*
81
* Save argc to the register structure for userspace.
82
*/
83
regs.UCreg_00 = ret;
84
85
/*
86
* We were successful. We won't be returning to our caller, but
87
* instead to user space by manipulating the kernel stack.
88
*/
89
asm("add r0, %0, %1\n\t"
90
"mov r1, %2\n\t"
91
"mov r2, %3\n\t"
92
"mov r22, #0\n\t" /* not a syscall */
93
"mov r23, %0\n\t" /* thread structure */
94
"b.l memmove\n\t" /* copy regs to top of stack */
95
"mov sp, r0\n\t" /* reposition stack pointer */
96
"b ret_to_user"
97
:
98
: "r" (current_thread_info()),
99
"Ir" (THREAD_START_SP - sizeof(regs)),
100
"r" (&regs),
101
"Ir" (sizeof(regs))
102
: "r0", "r1", "r2", "r3", "ip", "lr", "memory");
103
104
out:
105
return ret;
106
}
107
EXPORT_SYMBOL(kernel_execve);
108
109
/* Note: used by the compat code even in 64-bit Linux. */
110
SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len,
111
unsigned long, prot, unsigned long, flags,
112
unsigned long, fd, unsigned long, off_4k)
113
{
114
return sys_mmap_pgoff(addr, len, prot, flags, fd,
115
off_4k);
116
}
117
118
/* Provide the actual syscall number to call mapping. */
119
#undef __SYSCALL
120
#define __SYSCALL(nr, call) [nr] = (call),
121
122
/* Note that we don't include <linux/unistd.h> but <asm/unistd.h> */
123
void *sys_call_table[__NR_syscalls] = {
124
[0 ... __NR_syscalls-1] = sys_ni_syscall,
125
#include <asm/unistd.h>
126
};
127
128