diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-11-01 20:48:19 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-11-01 20:48:19 -0400 |
commit | c660b8f944f1815494a76935148571276fa47462 (patch) | |
tree | a6b98740870bb455e477782ad46c4a7d3892f1da /arch | |
parent | 8c23f406c6d86808726ace580657186bc3b44587 (diff) | |
parent | dc241f2c1761bfdec85915f4bbf7e750663f3442 (diff) |
Merge tag 'xtensa-next-20121101' of git://github.com/czankel/xtensa-linux
Pull Xtensa fixes from Chris Zankel:
"Some important bug fixes.
With the change to uapi, there was a bug introduced that results in an
empty syscall table (mult-inclusion bug). Switching to the generic
thread/execve allowed us to fix a bug we had in vfork()."
* tag 'xtensa-next-20121101' of git://github.com/czankel/xtensa-linux:
xtensa: switch to generic sys_execve()
xtensa: switch to generic kernel_execve()
xtensa: switch to generic kernel_thread()
xtensa: reset windowbase/windowstart when cloning the VM
xtensa: use physical addresses for bus addresses
xtensa: allow multi-inclusion for uapi/unistd.h
Diffstat (limited to 'arch')
-rw-r--r-- | arch/xtensa/Kconfig | 2 | ||||
-rw-r--r-- | arch/xtensa/include/asm/io.h | 4 | ||||
-rw-r--r-- | arch/xtensa/include/asm/processor.h | 4 | ||||
-rw-r--r-- | arch/xtensa/include/asm/syscall.h | 2 | ||||
-rw-r--r-- | arch/xtensa/include/asm/unistd.h | 15 | ||||
-rw-r--r-- | arch/xtensa/include/uapi/asm/unistd.h | 16 | ||||
-rw-r--r-- | arch/xtensa/kernel/entry.S | 57 | ||||
-rw-r--r-- | arch/xtensa/kernel/process.c | 128 | ||||
-rw-r--r-- | arch/xtensa/kernel/syscall.c | 7 | ||||
-rw-r--r-- | arch/xtensa/kernel/xtensa_ksyms.c | 1 |
10 files changed, 104 insertions, 132 deletions
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index cdcb48adee4c..0d1f36a22c98 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig | |||
@@ -13,6 +13,8 @@ config XTENSA | |||
13 | select GENERIC_CPU_DEVICES | 13 | select GENERIC_CPU_DEVICES |
14 | select MODULES_USE_ELF_RELA | 14 | select MODULES_USE_ELF_RELA |
15 | select GENERIC_PCI_IOMAP | 15 | select GENERIC_PCI_IOMAP |
16 | select GENERIC_KERNEL_THREAD | ||
17 | select GENERIC_KERNEL_EXECVE | ||
16 | select ARCH_WANT_OPTIONAL_GPIOLIB | 18 | select ARCH_WANT_OPTIONAL_GPIOLIB |
17 | help | 19 | help |
18 | Xtensa processors are 32-bit RISC machines designed by Tensilica | 20 | Xtensa processors are 32-bit RISC machines designed by Tensilica |
diff --git a/arch/xtensa/include/asm/io.h b/arch/xtensa/include/asm/io.h index e6be5b9091c2..700c2e6f2d25 100644 --- a/arch/xtensa/include/asm/io.h +++ b/arch/xtensa/include/asm/io.h | |||
@@ -62,6 +62,10 @@ static inline void __iomem *ioremap(unsigned long offset, unsigned long size) | |||
62 | static inline void iounmap(volatile void __iomem *addr) | 62 | static inline void iounmap(volatile void __iomem *addr) |
63 | { | 63 | { |
64 | } | 64 | } |
65 | |||
66 | #define virt_to_bus virt_to_phys | ||
67 | #define bus_to_virt phys_to_virt | ||
68 | |||
65 | #endif /* CONFIG_MMU */ | 69 | #endif /* CONFIG_MMU */ |
66 | 70 | ||
67 | /* | 71 | /* |
diff --git a/arch/xtensa/include/asm/processor.h b/arch/xtensa/include/asm/processor.h index 5c371d8d4528..2d630e7399ca 100644 --- a/arch/xtensa/include/asm/processor.h +++ b/arch/xtensa/include/asm/processor.h | |||
@@ -152,6 +152,7 @@ struct thread_struct { | |||
152 | 152 | ||
153 | /* Clearing a0 terminates the backtrace. */ | 153 | /* Clearing a0 terminates the backtrace. */ |
154 | #define start_thread(regs, new_pc, new_sp) \ | 154 | #define start_thread(regs, new_pc, new_sp) \ |
155 | memset(regs, 0, sizeof(*regs)); \ | ||
155 | regs->pc = new_pc; \ | 156 | regs->pc = new_pc; \ |
156 | regs->ps = USER_PS_VALUE; \ | 157 | regs->ps = USER_PS_VALUE; \ |
157 | regs->areg[1] = new_sp; \ | 158 | regs->areg[1] = new_sp; \ |
@@ -168,9 +169,6 @@ struct mm_struct; | |||
168 | /* Free all resources held by a thread. */ | 169 | /* Free all resources held by a thread. */ |
169 | #define release_thread(thread) do { } while(0) | 170 | #define release_thread(thread) do { } while(0) |
170 | 171 | ||
171 | /* Create a kernel thread without removing it from tasklists */ | ||
172 | extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); | ||
173 | |||
174 | /* Copy and release all segment info associated with a VM */ | 172 | /* Copy and release all segment info associated with a VM */ |
175 | #define copy_segments(p, mm) do { } while(0) | 173 | #define copy_segments(p, mm) do { } while(0) |
176 | #define release_segments(mm) do { } while(0) | 174 | #define release_segments(mm) do { } while(0) |
diff --git a/arch/xtensa/include/asm/syscall.h b/arch/xtensa/include/asm/syscall.h index c1dacca312f3..124aeee0d381 100644 --- a/arch/xtensa/include/asm/syscall.h +++ b/arch/xtensa/include/asm/syscall.h | |||
@@ -10,7 +10,7 @@ | |||
10 | 10 | ||
11 | struct pt_regs; | 11 | struct pt_regs; |
12 | struct sigaction; | 12 | struct sigaction; |
13 | asmlinkage long xtensa_execve(char*, char**, char**, struct pt_regs*); | 13 | asmlinkage long sys_execve(char*, char**, char**, struct pt_regs*); |
14 | asmlinkage long xtensa_clone(unsigned long, unsigned long, struct pt_regs*); | 14 | asmlinkage long xtensa_clone(unsigned long, unsigned long, struct pt_regs*); |
15 | asmlinkage long xtensa_ptrace(long, long, long, long); | 15 | asmlinkage long xtensa_ptrace(long, long, long, long); |
16 | asmlinkage long xtensa_sigreturn(struct pt_regs*); | 16 | asmlinkage long xtensa_sigreturn(struct pt_regs*); |
diff --git a/arch/xtensa/include/asm/unistd.h b/arch/xtensa/include/asm/unistd.h index 9ef1c31d2c83..f4e6eaa40d1c 100644 --- a/arch/xtensa/include/asm/unistd.h +++ b/arch/xtensa/include/asm/unistd.h | |||
@@ -1,16 +1,9 @@ | |||
1 | /* | 1 | #ifndef _XTENSA_UNISTD_H |
2 | * include/asm-xtensa/unistd.h | 2 | #define _XTENSA_UNISTD_H |
3 | * | ||
4 | * This file is subject to the terms and conditions of the GNU General Public | ||
5 | * License. See the file "COPYING" in the main directory of this archive | ||
6 | * for more details. | ||
7 | * | ||
8 | * Copyright (C) 2001 - 2005 Tensilica Inc. | ||
9 | */ | ||
10 | 3 | ||
4 | #define __ARCH_WANT_SYS_EXECVE | ||
11 | #include <uapi/asm/unistd.h> | 5 | #include <uapi/asm/unistd.h> |
12 | 6 | ||
13 | |||
14 | /* | 7 | /* |
15 | * "Conditional" syscalls | 8 | * "Conditional" syscalls |
16 | * | 9 | * |
@@ -37,3 +30,5 @@ | |||
37 | #define __IGNORE_mmap /* use mmap2 */ | 30 | #define __IGNORE_mmap /* use mmap2 */ |
38 | #define __IGNORE_vfork /* use clone */ | 31 | #define __IGNORE_vfork /* use clone */ |
39 | #define __IGNORE_fadvise64 /* use fadvise64_64 */ | 32 | #define __IGNORE_fadvise64 /* use fadvise64_64 */ |
33 | |||
34 | #endif /* _XTENSA_UNISTD_H */ | ||
diff --git a/arch/xtensa/include/uapi/asm/unistd.h b/arch/xtensa/include/uapi/asm/unistd.h index 479abaea5aae..9f36d0e3e0ac 100644 --- a/arch/xtensa/include/uapi/asm/unistd.h +++ b/arch/xtensa/include/uapi/asm/unistd.h | |||
@@ -1,14 +1,4 @@ | |||
1 | /* | 1 | #if !defined(_UAPI_XTENSA_UNISTD_H) || defined(__SYSCALL) |
2 | * include/asm-xtensa/unistd.h | ||
3 | * | ||
4 | * This file is subject to the terms and conditions of the GNU General Public | ||
5 | * License. See the file "COPYING" in the main directory of this archive | ||
6 | * for more details. | ||
7 | * | ||
8 | * Copyright (C) 2001 - 2012 Tensilica Inc. | ||
9 | */ | ||
10 | |||
11 | #ifndef _UAPI_XTENSA_UNISTD_H | ||
12 | #define _UAPI_XTENSA_UNISTD_H | 2 | #define _UAPI_XTENSA_UNISTD_H |
13 | 3 | ||
14 | #ifndef __SYSCALL | 4 | #ifndef __SYSCALL |
@@ -272,7 +262,7 @@ __SYSCALL(115, sys_sendmmsg, 4) | |||
272 | #define __NR_clone 116 | 262 | #define __NR_clone 116 |
273 | __SYSCALL(116, xtensa_clone, 5) | 263 | __SYSCALL(116, xtensa_clone, 5) |
274 | #define __NR_execve 117 | 264 | #define __NR_execve 117 |
275 | __SYSCALL(117, xtensa_execve, 3) | 265 | __SYSCALL(117, sys_execve, 3) |
276 | #define __NR_exit 118 | 266 | #define __NR_exit 118 |
277 | __SYSCALL(118, sys_exit, 1) | 267 | __SYSCALL(118, sys_exit, 1) |
278 | #define __NR_exit_group 119 | 268 | #define __NR_exit_group 119 |
@@ -759,4 +749,6 @@ __SYSCALL(331, sys_kcmp, 5) | |||
759 | 749 | ||
760 | #define SYS_XTENSA_COUNT 5 /* count */ | 750 | #define SYS_XTENSA_COUNT 5 /* count */ |
761 | 751 | ||
752 | #undef __SYSCALL | ||
753 | |||
762 | #endif /* _UAPI_XTENSA_UNISTD_H */ | 754 | #endif /* _UAPI_XTENSA_UNISTD_H */ |
diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S index 18453067c258..90bfc1dbc13d 100644 --- a/arch/xtensa/kernel/entry.S +++ b/arch/xtensa/kernel/entry.S | |||
@@ -1833,50 +1833,6 @@ ENTRY(system_call) | |||
1833 | 1833 | ||
1834 | 1834 | ||
1835 | /* | 1835 | /* |
1836 | * Create a kernel thread | ||
1837 | * | ||
1838 | * int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) | ||
1839 | * a2 a2 a3 a4 | ||
1840 | */ | ||
1841 | |||
1842 | ENTRY(kernel_thread) | ||
1843 | entry a1, 16 | ||
1844 | |||
1845 | mov a5, a2 # preserve fn over syscall | ||
1846 | mov a7, a3 # preserve args over syscall | ||
1847 | |||
1848 | movi a3, _CLONE_VM | _CLONE_UNTRACED | ||
1849 | movi a2, __NR_clone | ||
1850 | or a6, a4, a3 # arg0: flags | ||
1851 | mov a3, a1 # arg1: sp | ||
1852 | syscall | ||
1853 | |||
1854 | beq a3, a1, 1f # branch if parent | ||
1855 | mov a6, a7 # args | ||
1856 | callx4 a5 # fn(args) | ||
1857 | |||
1858 | movi a2, __NR_exit | ||
1859 | syscall # return value of fn(args) still in a6 | ||
1860 | |||
1861 | 1: retw | ||
1862 | |||
1863 | /* | ||
1864 | * Do a system call from kernel instead of calling sys_execve, so we end up | ||
1865 | * with proper pt_regs. | ||
1866 | * | ||
1867 | * int kernel_execve(const char *fname, char *const argv[], charg *const envp[]) | ||
1868 | * a2 a2 a3 a4 | ||
1869 | */ | ||
1870 | |||
1871 | ENTRY(kernel_execve) | ||
1872 | entry a1, 16 | ||
1873 | mov a6, a2 # arg0 is in a6 | ||
1874 | movi a2, __NR_execve | ||
1875 | syscall | ||
1876 | |||
1877 | retw | ||
1878 | |||
1879 | /* | ||
1880 | * Task switch. | 1836 | * Task switch. |
1881 | * | 1837 | * |
1882 | * struct task* _switch_to (struct task* prev, struct task* next) | 1838 | * struct task* _switch_to (struct task* prev, struct task* next) |
@@ -1958,3 +1914,16 @@ ENTRY(ret_from_fork) | |||
1958 | 1914 | ||
1959 | j common_exception_return | 1915 | j common_exception_return |
1960 | 1916 | ||
1917 | /* | ||
1918 | * Kernel thread creation helper | ||
1919 | * On entry, set up by copy_thread: a2 = thread_fn, a3 = thread_fn arg | ||
1920 | * left from _switch_to: a6 = prev | ||
1921 | */ | ||
1922 | ENTRY(ret_from_kernel_thread) | ||
1923 | |||
1924 | call4 schedule_tail | ||
1925 | mov a6, a3 | ||
1926 | callx4 a2 | ||
1927 | j common_exception_return | ||
1928 | |||
1929 | ENDPROC(ret_from_kernel_thread) | ||
diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c index 1908f6642d31..09ae7bfab9a7 100644 --- a/arch/xtensa/kernel/process.c +++ b/arch/xtensa/kernel/process.c | |||
@@ -45,6 +45,7 @@ | |||
45 | #include <asm/regs.h> | 45 | #include <asm/regs.h> |
46 | 46 | ||
47 | extern void ret_from_fork(void); | 47 | extern void ret_from_fork(void); |
48 | extern void ret_from_kernel_thread(void); | ||
48 | 49 | ||
49 | struct task_struct *current_set[NR_CPUS] = {&init_task, }; | 50 | struct task_struct *current_set[NR_CPUS] = {&init_task, }; |
50 | 51 | ||
@@ -158,18 +159,30 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) | |||
158 | /* | 159 | /* |
159 | * Copy thread. | 160 | * Copy thread. |
160 | * | 161 | * |
162 | * There are two modes in which this function is called: | ||
163 | * 1) Userspace thread creation, | ||
164 | * regs != NULL, usp_thread_fn is userspace stack pointer. | ||
165 | * It is expected to copy parent regs (in case CLONE_VM is not set | ||
166 | * in the clone_flags) and set up passed usp in the childregs. | ||
167 | * 2) Kernel thread creation, | ||
168 | * regs == NULL, usp_thread_fn is the function to run in the new thread | ||
169 | * and thread_fn_arg is its parameter. | ||
170 | * childregs are not used for the kernel threads. | ||
171 | * | ||
161 | * The stack layout for the new thread looks like this: | 172 | * The stack layout for the new thread looks like this: |
162 | * | 173 | * |
163 | * +------------------------+ <- sp in childregs (= tos) | 174 | * +------------------------+ |
164 | * | childregs | | 175 | * | childregs | |
165 | * +------------------------+ <- thread.sp = sp in dummy-frame | 176 | * +------------------------+ <- thread.sp = sp in dummy-frame |
166 | * | dummy-frame | (saved in dummy-frame spill-area) | 177 | * | dummy-frame | (saved in dummy-frame spill-area) |
167 | * +------------------------+ | 178 | * +------------------------+ |
168 | * | 179 | * |
169 | * We create a dummy frame to return to ret_from_fork: | 180 | * We create a dummy frame to return to either ret_from_fork or |
170 | * a0 points to ret_from_fork (simulating a call4) | 181 | * ret_from_kernel_thread: |
182 | * a0 points to ret_from_fork/ret_from_kernel_thread (simulating a call4) | ||
171 | * sp points to itself (thread.sp) | 183 | * sp points to itself (thread.sp) |
172 | * a2, a3 are unused. | 184 | * a2, a3 are unused for userspace threads, |
185 | * a2 points to thread_fn, a3 holds thread_fn arg for kernel threads. | ||
173 | * | 186 | * |
174 | * Note: This is a pristine frame, so we don't need any spill region on top of | 187 | * Note: This is a pristine frame, so we don't need any spill region on top of |
175 | * childregs. | 188 | * childregs. |
@@ -185,43 +198,63 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) | |||
185 | * involved. Much simpler to just not copy those live frames across. | 198 | * involved. Much simpler to just not copy those live frames across. |
186 | */ | 199 | */ |
187 | 200 | ||
188 | int copy_thread(unsigned long clone_flags, unsigned long usp, | 201 | int copy_thread(unsigned long clone_flags, unsigned long usp_thread_fn, |
189 | unsigned long unused, | 202 | unsigned long thread_fn_arg, |
190 | struct task_struct * p, struct pt_regs * regs) | 203 | struct task_struct *p, struct pt_regs *unused) |
191 | { | 204 | { |
192 | struct pt_regs *childregs; | 205 | struct pt_regs *childregs = task_pt_regs(p); |
193 | unsigned long tos; | ||
194 | int user_mode = user_mode(regs); | ||
195 | 206 | ||
196 | #if (XTENSA_HAVE_COPROCESSORS || XTENSA_HAVE_IO_PORTS) | 207 | #if (XTENSA_HAVE_COPROCESSORS || XTENSA_HAVE_IO_PORTS) |
197 | struct thread_info *ti; | 208 | struct thread_info *ti; |
198 | #endif | 209 | #endif |
199 | 210 | ||
200 | /* Set up new TSS. */ | ||
201 | tos = (unsigned long)task_stack_page(p) + THREAD_SIZE; | ||
202 | if (user_mode) | ||
203 | childregs = (struct pt_regs*)(tos - PT_USER_SIZE); | ||
204 | else | ||
205 | childregs = (struct pt_regs*)tos - 1; | ||
206 | |||
207 | /* This does not copy all the regs. In a bout of brilliance or madness, | ||
208 | ARs beyond a0-a15 exist past the end of the struct. */ | ||
209 | *childregs = *regs; | ||
210 | |||
211 | /* Create a call4 dummy-frame: a0 = 0, a1 = childregs. */ | 211 | /* Create a call4 dummy-frame: a0 = 0, a1 = childregs. */ |
212 | *((int*)childregs - 3) = (unsigned long)childregs; | 212 | *((int*)childregs - 3) = (unsigned long)childregs; |
213 | *((int*)childregs - 4) = 0; | 213 | *((int*)childregs - 4) = 0; |
214 | 214 | ||
215 | childregs->areg[2] = 0; | ||
216 | p->set_child_tid = p->clear_child_tid = NULL; | ||
217 | p->thread.ra = MAKE_RA_FOR_CALL((unsigned long)ret_from_fork, 0x1); | ||
218 | p->thread.sp = (unsigned long)childregs; | 215 | p->thread.sp = (unsigned long)childregs; |
219 | 216 | ||
220 | if (user_mode(regs)) { | 217 | if (!(p->flags & PF_KTHREAD)) { |
218 | struct pt_regs *regs = current_pt_regs(); | ||
219 | unsigned long usp = usp_thread_fn ? | ||
220 | usp_thread_fn : regs->areg[1]; | ||
221 | 221 | ||
222 | p->thread.ra = MAKE_RA_FOR_CALL( | ||
223 | (unsigned long)ret_from_fork, 0x1); | ||
224 | |||
225 | /* This does not copy all the regs. | ||
226 | * In a bout of brilliance or madness, | ||
227 | * ARs beyond a0-a15 exist past the end of the struct. | ||
228 | */ | ||
229 | *childregs = *regs; | ||
222 | childregs->areg[1] = usp; | 230 | childregs->areg[1] = usp; |
231 | childregs->areg[2] = 0; | ||
232 | |||
233 | /* When sharing memory with the parent thread, the child | ||
234 | usually starts on a pristine stack, so we have to reset | ||
235 | windowbase, windowstart and wmask. | ||
236 | (Note that such a new thread is required to always create | ||
237 | an initial call4 frame) | ||
238 | The exception is vfork, where the new thread continues to | ||
239 | run on the parent's stack until it calls execve. This could | ||
240 | be a call8 or call12, which requires a legal stack frame | ||
241 | of the previous caller for the overflow handlers to work. | ||
242 | (Note that it's always legal to overflow live registers). | ||
243 | In this case, ensure to spill at least the stack pointer | ||
244 | of that frame. */ | ||
245 | |||
223 | if (clone_flags & CLONE_VM) { | 246 | if (clone_flags & CLONE_VM) { |
224 | childregs->wmask = 1; /* can't share live windows */ | 247 | /* check that caller window is live and same stack */ |
248 | int len = childregs->wmask & ~0xf; | ||
249 | if (regs->areg[1] == usp && len != 0) { | ||
250 | int callinc = (regs->areg[0] >> 30) & 3; | ||
251 | int caller_ars = XCHAL_NUM_AREGS - callinc * 4; | ||
252 | put_user(regs->areg[caller_ars+1], | ||
253 | (unsigned __user*)(usp - 12)); | ||
254 | } | ||
255 | childregs->wmask = 1; | ||
256 | childregs->windowstart = 1; | ||
257 | childregs->windowbase = 0; | ||
225 | } else { | 258 | } else { |
226 | int len = childregs->wmask & ~0xf; | 259 | int len = childregs->wmask & ~0xf; |
227 | memcpy(&childregs->areg[XCHAL_NUM_AREGS - len/4], | 260 | memcpy(&childregs->areg[XCHAL_NUM_AREGS - len/4], |
@@ -230,11 +263,19 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, | |||
230 | // FIXME: we need to set THREADPTR in thread_info... | 263 | // FIXME: we need to set THREADPTR in thread_info... |
231 | if (clone_flags & CLONE_SETTLS) | 264 | if (clone_flags & CLONE_SETTLS) |
232 | childregs->areg[2] = childregs->areg[6]; | 265 | childregs->areg[2] = childregs->areg[6]; |
233 | |||
234 | } else { | 266 | } else { |
235 | /* In kernel space, we start a new thread with a new stack. */ | 267 | p->thread.ra = MAKE_RA_FOR_CALL( |
236 | childregs->wmask = 1; | 268 | (unsigned long)ret_from_kernel_thread, 1); |
237 | childregs->areg[1] = tos; | 269 | |
270 | /* pass parameters to ret_from_kernel_thread: | ||
271 | * a2 = thread_fn, a3 = thread_fn arg | ||
272 | */ | ||
273 | *((int *)childregs - 1) = thread_fn_arg; | ||
274 | *((int *)childregs - 2) = usp_thread_fn; | ||
275 | |||
276 | /* Childregs are only used when we're going to userspace | ||
277 | * in which case start_thread will set them up. | ||
278 | */ | ||
238 | } | 279 | } |
239 | 280 | ||
240 | #if (XTENSA_HAVE_COPROCESSORS || XTENSA_HAVE_IO_PORTS) | 281 | #if (XTENSA_HAVE_COPROCESSORS || XTENSA_HAVE_IO_PORTS) |
@@ -330,32 +371,5 @@ long xtensa_clone(unsigned long clone_flags, unsigned long newsp, | |||
330 | void __user *child_tid, long a5, | 371 | void __user *child_tid, long a5, |
331 | struct pt_regs *regs) | 372 | struct pt_regs *regs) |
332 | { | 373 | { |
333 | if (!newsp) | ||
334 | newsp = regs->areg[1]; | ||
335 | return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid); | 374 | return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid); |
336 | } | 375 | } |
337 | |||
338 | /* | ||
339 | * xtensa_execve() executes a new program. | ||
340 | */ | ||
341 | |||
342 | asmlinkage | ||
343 | long xtensa_execve(const char __user *name, | ||
344 | const char __user *const __user *argv, | ||
345 | const char __user *const __user *envp, | ||
346 | long a3, long a4, long a5, | ||
347 | struct pt_regs *regs) | ||
348 | { | ||
349 | long error; | ||
350 | struct filename *filename; | ||
351 | |||
352 | filename = getname(name); | ||
353 | error = PTR_ERR(filename); | ||
354 | if (IS_ERR(filename)) | ||
355 | goto out; | ||
356 | error = do_execve(filename->name, argv, envp, regs); | ||
357 | putname(filename); | ||
358 | out: | ||
359 | return error; | ||
360 | } | ||
361 | |||
diff --git a/arch/xtensa/kernel/syscall.c b/arch/xtensa/kernel/syscall.c index a5c01e74d5d5..5702065f472a 100644 --- a/arch/xtensa/kernel/syscall.c +++ b/arch/xtensa/kernel/syscall.c | |||
@@ -32,10 +32,8 @@ typedef void (*syscall_t)(void); | |||
32 | syscall_t sys_call_table[__NR_syscall_count] /* FIXME __cacheline_aligned */= { | 32 | syscall_t sys_call_table[__NR_syscall_count] /* FIXME __cacheline_aligned */= { |
33 | [0 ... __NR_syscall_count - 1] = (syscall_t)&sys_ni_syscall, | 33 | [0 ... __NR_syscall_count - 1] = (syscall_t)&sys_ni_syscall, |
34 | 34 | ||
35 | #undef __SYSCALL | ||
36 | #define __SYSCALL(nr,symbol,nargs) [ nr ] = (syscall_t)symbol, | 35 | #define __SYSCALL(nr,symbol,nargs) [ nr ] = (syscall_t)symbol, |
37 | #undef __KERNEL_SYSCALLS__ | 36 | #include <uapi/asm/unistd.h> |
38 | #include <asm/unistd.h> | ||
39 | }; | 37 | }; |
40 | 38 | ||
41 | asmlinkage long xtensa_shmat(int shmid, char __user *shmaddr, int shmflg) | 39 | asmlinkage long xtensa_shmat(int shmid, char __user *shmaddr, int shmflg) |
@@ -49,7 +47,8 @@ asmlinkage long xtensa_shmat(int shmid, char __user *shmaddr, int shmflg) | |||
49 | return (long)ret; | 47 | return (long)ret; |
50 | } | 48 | } |
51 | 49 | ||
52 | asmlinkage long xtensa_fadvise64_64(int fd, int advice, unsigned long long offset, unsigned long long len) | 50 | asmlinkage long xtensa_fadvise64_64(int fd, int advice, |
51 | unsigned long long offset, unsigned long long len) | ||
53 | { | 52 | { |
54 | return sys_fadvise64_64(fd, offset, len, advice); | 53 | return sys_fadvise64_64(fd, offset, len, advice); |
55 | } | 54 | } |
diff --git a/arch/xtensa/kernel/xtensa_ksyms.c b/arch/xtensa/kernel/xtensa_ksyms.c index a8b9f1fd1e17..afe058b24e6e 100644 --- a/arch/xtensa/kernel/xtensa_ksyms.c +++ b/arch/xtensa/kernel/xtensa_ksyms.c | |||
@@ -43,7 +43,6 @@ EXPORT_SYMBOL(__strncpy_user); | |||
43 | EXPORT_SYMBOL(clear_page); | 43 | EXPORT_SYMBOL(clear_page); |
44 | EXPORT_SYMBOL(copy_page); | 44 | EXPORT_SYMBOL(copy_page); |
45 | 45 | ||
46 | EXPORT_SYMBOL(kernel_thread); | ||
47 | EXPORT_SYMBOL(empty_zero_page); | 46 | EXPORT_SYMBOL(empty_zero_page); |
48 | 47 | ||
49 | /* | 48 | /* |