.. | .. |
---|
37 | 37 | #include <linux/slab.h> |
---|
38 | 38 | #include <linux/rcupdate.h> |
---|
39 | 39 | |
---|
40 | | -#include <asm/pgtable.h> |
---|
41 | 40 | #include <linux/uaccess.h> |
---|
42 | 41 | #include <asm/io.h> |
---|
43 | 42 | #include <asm/processor.h> |
---|
.. | .. |
---|
51 | 50 | |
---|
52 | 51 | extern void ret_from_fork(void); |
---|
53 | 52 | extern void ret_from_kernel_thread(void); |
---|
54 | | - |
---|
55 | | -struct task_struct *current_set[NR_CPUS] = {&init_task, }; |
---|
56 | 53 | |
---|
57 | 54 | void (*pm_power_off)(void) = NULL; |
---|
58 | 55 | EXPORT_SYMBOL(pm_power_off); |
---|
.. | .. |
---|
87 | 84 | } |
---|
88 | 85 | |
---|
89 | 86 | ti->cpenable = cpenable; |
---|
90 | | - coprocessor_clear_cpenable(); |
---|
| 87 | + if (ti == current_thread_info()) |
---|
| 88 | + xtensa_set_sr(0, cpenable); |
---|
91 | 89 | |
---|
92 | 90 | preempt_enable(); |
---|
93 | 91 | } |
---|
.. | .. |
---|
99 | 97 | |
---|
100 | 98 | preempt_disable(); |
---|
101 | 99 | |
---|
102 | | - RSR_CPENABLE(old_cpenable); |
---|
| 100 | + old_cpenable = xtensa_get_sr(cpenable); |
---|
103 | 101 | cpenable = ti->cpenable; |
---|
104 | | - WSR_CPENABLE(cpenable); |
---|
| 102 | + xtensa_set_sr(cpenable, cpenable); |
---|
105 | 103 | |
---|
106 | 104 | for (i = 0; i < XCHAL_CP_MAX; i++) { |
---|
107 | 105 | if ((cpenable & 1) != 0 && coprocessor_owner[i] == ti) |
---|
108 | 106 | coprocessor_flush(ti, i); |
---|
109 | 107 | cpenable >>= 1; |
---|
110 | 108 | } |
---|
111 | | - WSR_CPENABLE(old_cpenable); |
---|
| 109 | + xtensa_set_sr(old_cpenable, cpenable); |
---|
112 | 110 | |
---|
113 | 111 | preempt_enable(); |
---|
114 | 112 | } |
---|
.. | .. |
---|
204 | 202 | */ |
---|
205 | 203 | |
---|
206 | 204 | int copy_thread(unsigned long clone_flags, unsigned long usp_thread_fn, |
---|
207 | | - unsigned long thread_fn_arg, struct task_struct *p) |
---|
| 205 | + unsigned long thread_fn_arg, struct task_struct *p, |
---|
| 206 | + unsigned long tls) |
---|
208 | 207 | { |
---|
209 | 208 | struct pt_regs *childregs = task_pt_regs(p); |
---|
210 | 209 | |
---|
.. | .. |
---|
218 | 217 | |
---|
219 | 218 | p->thread.sp = (unsigned long)childregs; |
---|
220 | 219 | |
---|
221 | | - if (!(p->flags & PF_KTHREAD)) { |
---|
| 220 | + if (!(p->flags & (PF_KTHREAD | PF_IO_WORKER))) { |
---|
222 | 221 | struct pt_regs *regs = current_pt_regs(); |
---|
223 | 222 | unsigned long usp = usp_thread_fn ? |
---|
224 | 223 | usp_thread_fn : regs->areg[1]; |
---|
.. | .. |
---|
265 | 264 | ®s->areg[XCHAL_NUM_AREGS - len/4], len); |
---|
266 | 265 | } |
---|
267 | 266 | |
---|
268 | | - /* The thread pointer is passed in the '4th argument' (= a5) */ |
---|
| 267 | + childregs->syscall = regs->syscall; |
---|
| 268 | + |
---|
269 | 269 | if (clone_flags & CLONE_SETTLS) |
---|
270 | | - childregs->threadptr = childregs->areg[5]; |
---|
| 270 | + childregs->threadptr = tls; |
---|
271 | 271 | } else { |
---|
272 | 272 | p->thread.ra = MAKE_RA_FOR_CALL( |
---|
273 | 273 | (unsigned long)ret_from_kernel_thread, 1); |
---|
.. | .. |
---|
323 | 323 | pc = MAKE_PC_FROM_RA(SPILL_SLOT(sp, 0), sp); |
---|
324 | 324 | sp = SPILL_SLOT(sp, 1); |
---|
325 | 325 | } while (count++ < 16); |
---|
326 | | - return 0; |
---|
327 | | -} |
---|
328 | | - |
---|
329 | | -/* |
---|
330 | | - * xtensa_gregset_t and 'struct pt_regs' are vastly different formats |
---|
331 | | - * of processor registers. Besides different ordering, |
---|
332 | | - * xtensa_gregset_t contains non-live register information that |
---|
333 | | - * 'struct pt_regs' does not. Exception handling (primarily) uses |
---|
334 | | - * 'struct pt_regs'. Core files and ptrace use xtensa_gregset_t. |
---|
335 | | - * |
---|
336 | | - */ |
---|
337 | | - |
---|
338 | | -void xtensa_elf_core_copy_regs (xtensa_gregset_t *elfregs, struct pt_regs *regs) |
---|
339 | | -{ |
---|
340 | | - unsigned long wb, ws, wm; |
---|
341 | | - int live, last; |
---|
342 | | - |
---|
343 | | - wb = regs->windowbase; |
---|
344 | | - ws = regs->windowstart; |
---|
345 | | - wm = regs->wmask; |
---|
346 | | - ws = ((ws >> wb) | (ws << (WSBITS - wb))) & ((1 << WSBITS) - 1); |
---|
347 | | - |
---|
348 | | - /* Don't leak any random bits. */ |
---|
349 | | - |
---|
350 | | - memset(elfregs, 0, sizeof(*elfregs)); |
---|
351 | | - |
---|
352 | | - /* Note: PS.EXCM is not set while user task is running; its |
---|
353 | | - * being set in regs->ps is for exception handling convenience. |
---|
354 | | - */ |
---|
355 | | - |
---|
356 | | - elfregs->pc = regs->pc; |
---|
357 | | - elfregs->ps = (regs->ps & ~(1 << PS_EXCM_BIT)); |
---|
358 | | - elfregs->lbeg = regs->lbeg; |
---|
359 | | - elfregs->lend = regs->lend; |
---|
360 | | - elfregs->lcount = regs->lcount; |
---|
361 | | - elfregs->sar = regs->sar; |
---|
362 | | - elfregs->windowstart = ws; |
---|
363 | | - |
---|
364 | | - live = (wm & 2) ? 4 : (wm & 4) ? 8 : (wm & 8) ? 12 : 16; |
---|
365 | | - last = XCHAL_NUM_AREGS - (wm >> 4) * 4; |
---|
366 | | - memcpy(elfregs->a, regs->areg, live * 4); |
---|
367 | | - memcpy(elfregs->a + last, regs->areg + last, (wm >> 4) * 16); |
---|
368 | | -} |
---|
369 | | - |
---|
370 | | -int dump_fpu(void) |
---|
371 | | -{ |
---|
372 | 326 | return 0; |
---|
373 | 327 | } |
---|