Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+104 -132
+2
arch/xtensa/Kconfig
··· 13 13 select GENERIC_CPU_DEVICES 14 14 select MODULES_USE_ELF_RELA 15 15 select GENERIC_PCI_IOMAP 16 + select GENERIC_KERNEL_THREAD 17 + select GENERIC_KERNEL_EXECVE 16 18 select ARCH_WANT_OPTIONAL_GPIOLIB 17 19 help 18 20 Xtensa processors are 32-bit RISC machines designed by Tensilica
+4
arch/xtensa/include/asm/io.h
··· 62 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 69 #endif /* CONFIG_MMU */ 66 70 67 71 /*
+1 -3
arch/xtensa/include/asm/processor.h
··· 152 152 153 153 /* Clearing a0 terminates the backtrace. */ 154 154 #define start_thread(regs, new_pc, new_sp) \ 155 + memset(regs, 0, sizeof(*regs)); \ 155 156 regs->pc = new_pc; \ 156 157 regs->ps = USER_PS_VALUE; \ 157 158 regs->areg[1] = new_sp; \ ··· 168 167 169 168 /* Free all resources held by a thread. */ 170 169 #define release_thread(thread) do { } while(0) 171 - 172 - /* Create a kernel thread without removing it from tasklists */ 173 - extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); 174 170 175 171 /* Copy and release all segment info associated with a VM */ 176 172 #define copy_segments(p, mm) do { } while(0)
+1 -1
arch/xtensa/include/asm/syscall.h
··· 10 10 11 11 struct pt_regs; 12 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 14 asmlinkage long xtensa_clone(unsigned long, unsigned long, struct pt_regs*); 15 15 asmlinkage long xtensa_ptrace(long, long, long, long); 16 16 asmlinkage long xtensa_sigreturn(struct pt_regs*);
+5 -10
arch/xtensa/include/asm/unistd.h
··· 1 - /* 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 - 2005 Tensilica Inc. 9 - */ 1 + #ifndef _XTENSA_UNISTD_H 2 + #define _XTENSA_UNISTD_H 10 3 4 + #define __ARCH_WANT_SYS_EXECVE 11 5 #include <uapi/asm/unistd.h> 12 - 13 6 14 7 /* 15 8 * "Conditional" syscalls ··· 30 37 #define __IGNORE_mmap /* use mmap2 */ 31 38 #define __IGNORE_vfork /* use clone */ 32 39 #define __IGNORE_fadvise64 /* use fadvise64_64 */ 40 + 41 + #endif /* _XTENSA_UNISTD_H */
+4 -12
arch/xtensa/include/uapi/asm/unistd.h
··· 1 - /* 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 1 + #if !defined(_UAPI_XTENSA_UNISTD_H) || defined(__SYSCALL) 12 2 #define _UAPI_XTENSA_UNISTD_H 13 3 14 4 #ifndef __SYSCALL ··· 262 272 #define __NR_clone 116 263 273 __SYSCALL(116, xtensa_clone, 5) 264 274 #define __NR_execve 117 265 - __SYSCALL(117, xtensa_execve, 3) 275 + __SYSCALL(117, sys_execve, 3) 266 276 #define __NR_exit 118 267 277 __SYSCALL(118, sys_exit, 1) 268 278 #define __NR_exit_group 119 ··· 748 758 #define SYS_XTENSA_ATOMIC_CMP_SWP 4 /* compare and swap */ 749 759 750 760 #define SYS_XTENSA_COUNT 5 /* count */ 761 + 762 + #undef __SYSCALL 751 763 752 764 #endif /* _UAPI_XTENSA_UNISTD_H */
+13 -44
arch/xtensa/kernel/entry.S
··· 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 1836 * Task switch. 1881 1837 * 1882 1838 * struct task* _switch_to (struct task* prev, struct task* next) ··· 1914 1958 1915 1959 j common_exception_return 1916 1960 1961 + /* 1962 + * Kernel thread creation helper 1963 + * On entry, set up by copy_thread: a2 = thread_fn, a3 = thread_fn arg 1964 + * left from _switch_to: a6 = prev 1965 + */ 1966 + ENTRY(ret_from_kernel_thread) 1967 + 1968 + call4 schedule_tail 1969 + mov a6, a3 1970 + callx4 a2 1971 + j common_exception_return 1972 + 1973 + ENDPROC(ret_from_kernel_thread)
+71 -57
arch/xtensa/kernel/process.c
··· 45 45 #include <asm/regs.h> 46 46 47 47 extern void ret_from_fork(void); 48 + extern void ret_from_kernel_thread(void); 48 49 49 50 struct task_struct *current_set[NR_CPUS] = {&init_task, }; 50 51 ··· 159 158 /* 160 159 * Copy thread. 161 160 * 161 + * There are two modes in which this function is called: 162 + * 1) Userspace thread creation, 163 + * regs != NULL, usp_thread_fn is userspace stack pointer. 164 + * It is expected to copy parent regs (in case CLONE_VM is not set 165 + * in the clone_flags) and set up passed usp in the childregs. 166 + * 2) Kernel thread creation, 167 + * regs == NULL, usp_thread_fn is the function to run in the new thread 168 + * and thread_fn_arg is its parameter. 169 + * childregs are not used for the kernel threads. 170 + * 162 171 * The stack layout for the new thread looks like this: 163 172 * 164 - * +------------------------+ <- sp in childregs (= tos) 173 + * +------------------------+ 165 174 * | childregs | 166 175 * +------------------------+ <- thread.sp = sp in dummy-frame 167 176 * | dummy-frame | (saved in dummy-frame spill-area) 168 177 * +------------------------+ 169 178 * 170 - * We create a dummy frame to return to ret_from_fork: 171 - * a0 points to ret_from_fork (simulating a call4) 179 + * We create a dummy frame to return to either ret_from_fork or 180 + * ret_from_kernel_thread: 181 + * a0 points to ret_from_fork/ret_from_kernel_thread (simulating a call4) 172 182 * sp points to itself (thread.sp) 173 - * a2, a3 are unused. 183 + * a2, a3 are unused for userspace threads, 184 + * a2 points to thread_fn, a3 holds thread_fn arg for kernel threads. 174 185 * 175 186 * Note: This is a pristine frame, so we don't need any spill region on top of 176 187 * childregs. ··· 198 185 * involved. Much simpler to just not copy those live frames across. 199 186 */ 200 187 201 - int copy_thread(unsigned long clone_flags, unsigned long usp, 202 - unsigned long unused, 203 - struct task_struct * p, struct pt_regs * regs) 188 + int copy_thread(unsigned long clone_flags, unsigned long usp_thread_fn, 189 + unsigned long thread_fn_arg, 190 + struct task_struct *p, struct pt_regs *unused) 204 191 { 205 - struct pt_regs *childregs; 206 - unsigned long tos; 207 - int user_mode = user_mode(regs); 192 + struct pt_regs *childregs = task_pt_regs(p); 208 193 209 194 #if (XTENSA_HAVE_COPROCESSORS || XTENSA_HAVE_IO_PORTS) 210 195 struct thread_info *ti; 211 196 #endif 212 197 213 - /* Set up new TSS. */ 214 - tos = (unsigned long)task_stack_page(p) + THREAD_SIZE; 215 - if (user_mode) 216 - childregs = (struct pt_regs*)(tos - PT_USER_SIZE); 217 - else 218 - childregs = (struct pt_regs*)tos - 1; 219 - 220 - /* This does not copy all the regs. In a bout of brilliance or madness, 221 - ARs beyond a0-a15 exist past the end of the struct. */ 222 - *childregs = *regs; 223 - 224 198 /* Create a call4 dummy-frame: a0 = 0, a1 = childregs. */ 225 199 *((int*)childregs - 3) = (unsigned long)childregs; 226 200 *((int*)childregs - 4) = 0; 227 201 228 - childregs->areg[2] = 0; 229 - p->set_child_tid = p->clear_child_tid = NULL; 230 - p->thread.ra = MAKE_RA_FOR_CALL((unsigned long)ret_from_fork, 0x1); 231 202 p->thread.sp = (unsigned long)childregs; 232 203 233 - if (user_mode(regs)) { 204 + if (!(p->flags & PF_KTHREAD)) { 205 + struct pt_regs *regs = current_pt_regs(); 206 + unsigned long usp = usp_thread_fn ? 207 + usp_thread_fn : regs->areg[1]; 234 208 209 + p->thread.ra = MAKE_RA_FOR_CALL( 210 + (unsigned long)ret_from_fork, 0x1); 211 + 212 + /* This does not copy all the regs. 213 + * In a bout of brilliance or madness, 214 + * ARs beyond a0-a15 exist past the end of the struct. 215 + */ 216 + *childregs = *regs; 235 217 childregs->areg[1] = usp; 218 + childregs->areg[2] = 0; 219 + 220 + /* When sharing memory with the parent thread, the child 221 + usually starts on a pristine stack, so we have to reset 222 + windowbase, windowstart and wmask. 223 + (Note that such a new thread is required to always create 224 + an initial call4 frame) 225 + The exception is vfork, where the new thread continues to 226 + run on the parent's stack until it calls execve. This could 227 + be a call8 or call12, which requires a legal stack frame 228 + of the previous caller for the overflow handlers to work. 229 + (Note that it's always legal to overflow live registers). 230 + In this case, ensure to spill at least the stack pointer 231 + of that frame. */ 232 + 236 233 if (clone_flags & CLONE_VM) { 237 - childregs->wmask = 1; /* can't share live windows */ 234 + /* check that caller window is live and same stack */ 235 + int len = childregs->wmask & ~0xf; 236 + if (regs->areg[1] == usp && len != 0) { 237 + int callinc = (regs->areg[0] >> 30) & 3; 238 + int caller_ars = XCHAL_NUM_AREGS - callinc * 4; 239 + put_user(regs->areg[caller_ars+1], 240 + (unsigned __user*)(usp - 12)); 241 + } 242 + childregs->wmask = 1; 243 + childregs->windowstart = 1; 244 + childregs->windowbase = 0; 238 245 } else { 239 246 int len = childregs->wmask & ~0xf; 240 247 memcpy(&childregs->areg[XCHAL_NUM_AREGS - len/4], ··· 263 230 // FIXME: we need to set THREADPTR in thread_info... 264 231 if (clone_flags & CLONE_SETTLS) 265 232 childregs->areg[2] = childregs->areg[6]; 266 - 267 233 } else { 268 - /* In kernel space, we start a new thread with a new stack. */ 269 - childregs->wmask = 1; 270 - childregs->areg[1] = tos; 234 + p->thread.ra = MAKE_RA_FOR_CALL( 235 + (unsigned long)ret_from_kernel_thread, 1); 236 + 237 + /* pass parameters to ret_from_kernel_thread: 238 + * a2 = thread_fn, a3 = thread_fn arg 239 + */ 240 + *((int *)childregs - 1) = thread_fn_arg; 241 + *((int *)childregs - 2) = usp_thread_fn; 242 + 243 + /* Childregs are only used when we're going to userspace 244 + * in which case start_thread will set them up. 245 + */ 271 246 } 272 247 273 248 #if (XTENSA_HAVE_COPROCESSORS || XTENSA_HAVE_IO_PORTS) ··· 371 330 void __user *child_tid, long a5, 372 331 struct pt_regs *regs) 373 332 { 374 - if (!newsp) 375 - newsp = regs->areg[1]; 376 333 return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid); 377 334 } 378 - 379 - /* 380 - * xtensa_execve() executes a new program. 381 - */ 382 - 383 - asmlinkage 384 - long xtensa_execve(const char __user *name, 385 - const char __user *const __user *argv, 386 - const char __user *const __user *envp, 387 - long a3, long a4, long a5, 388 - struct pt_regs *regs) 389 - { 390 - long error; 391 - struct filename *filename; 392 - 393 - filename = getname(name); 394 - error = PTR_ERR(filename); 395 - if (IS_ERR(filename)) 396 - goto out; 397 - error = do_execve(filename->name, argv, envp, regs); 398 - putname(filename); 399 - out: 400 - return error; 401 - } 402 -
+3 -4
arch/xtensa/kernel/syscall.c
··· 32 32 syscall_t sys_call_table[__NR_syscall_count] /* FIXME __cacheline_aligned */= { 33 33 [0 ... __NR_syscall_count - 1] = (syscall_t)&sys_ni_syscall, 34 34 35 - #undef __SYSCALL 36 35 #define __SYSCALL(nr,symbol,nargs) [ nr ] = (syscall_t)symbol, 37 - #undef __KERNEL_SYSCALLS__ 38 - #include <asm/unistd.h> 36 + #include <uapi/asm/unistd.h> 39 37 }; 40 38 41 39 asmlinkage long xtensa_shmat(int shmid, char __user *shmaddr, int shmflg) ··· 47 49 return (long)ret; 48 50 } 49 51 50 - asmlinkage long xtensa_fadvise64_64(int fd, int advice, unsigned long long offset, unsigned long long len) 52 + asmlinkage long xtensa_fadvise64_64(int fd, int advice, 53 + unsigned long long offset, unsigned long long len) 51 54 { 52 55 return sys_fadvise64_64(fd, offset, len, advice); 53 56 }
-1
arch/xtensa/kernel/xtensa_ksyms.c
··· 43 43 EXPORT_SYMBOL(clear_page); 44 44 EXPORT_SYMBOL(copy_page); 45 45 46 - EXPORT_SYMBOL(kernel_thread); 47 46 EXPORT_SYMBOL(empty_zero_page); 48 47 49 48 /*