diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /arch/unicore32/kernel | |
parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) |
Patched in Tegra support.
Diffstat (limited to 'arch/unicore32/kernel')
-rw-r--r-- | arch/unicore32/kernel/Makefile | 3 | ||||
-rw-r--r-- | arch/unicore32/kernel/dma.c | 1 | ||||
-rw-r--r-- | arch/unicore32/kernel/entry.S | 28 | ||||
-rw-r--r-- | arch/unicore32/kernel/head.S | 2 | ||||
-rw-r--r-- | arch/unicore32/kernel/hibernate.c | 1 | ||||
-rw-r--r-- | arch/unicore32/kernel/irq.c | 1 | ||||
-rw-r--r-- | arch/unicore32/kernel/ksyms.c | 5 | ||||
-rw-r--r-- | arch/unicore32/kernel/module.c | 3 | ||||
-rw-r--r-- | arch/unicore32/kernel/pci.c | 24 | ||||
-rw-r--r-- | arch/unicore32/kernel/process.c | 72 | ||||
-rw-r--r-- | arch/unicore32/kernel/puv3-core.c | 1 | ||||
-rw-r--r-- | arch/unicore32/kernel/puv3-nb0916.c | 5 | ||||
-rw-r--r-- | arch/unicore32/kernel/setup.c | 3 | ||||
-rw-r--r-- | arch/unicore32/kernel/setup.h | 9 | ||||
-rw-r--r-- | arch/unicore32/kernel/signal.c | 69 | ||||
-rw-r--r-- | arch/unicore32/kernel/sys.c | 78 | ||||
-rw-r--r-- | arch/unicore32/kernel/time.c | 2 | ||||
-rw-r--r-- | arch/unicore32/kernel/traps.c | 1 |
18 files changed, 240 insertions, 68 deletions
diff --git a/arch/unicore32/kernel/Makefile b/arch/unicore32/kernel/Makefile index fa497e0efe5..aeb0f181568 100644 --- a/arch/unicore32/kernel/Makefile +++ b/arch/unicore32/kernel/Makefile | |||
@@ -16,6 +16,7 @@ obj-$(CONFIG_UNICORE_FPU_F64) += fpu-ucf64.o | |||
16 | obj-$(CONFIG_ARCH_PUV3) += clock.o irq.o time.o | 16 | obj-$(CONFIG_ARCH_PUV3) += clock.o irq.o time.o |
17 | 17 | ||
18 | obj-$(CONFIG_PUV3_GPIO) += gpio.o | 18 | obj-$(CONFIG_PUV3_GPIO) += gpio.o |
19 | obj-$(CONFIG_PUV3_PWM) += pwm.o | ||
19 | obj-$(CONFIG_PUV3_PM) += pm.o sleep.o | 20 | obj-$(CONFIG_PUV3_PM) += pm.o sleep.o |
20 | obj-$(CONFIG_HIBERNATION) += hibernate.o hibernate_asm.o | 21 | obj-$(CONFIG_HIBERNATION) += hibernate.o hibernate_asm.o |
21 | 22 | ||
@@ -28,4 +29,4 @@ obj-$(CONFIG_PUV3_NB0916) += puv3-nb0916.o | |||
28 | head-y := head.o | 29 | head-y := head.o |
29 | obj-$(CONFIG_DEBUG_LL) += debug.o | 30 | obj-$(CONFIG_DEBUG_LL) += debug.o |
30 | 31 | ||
31 | extra-y := $(head-y) vmlinux.lds | 32 | extra-y := $(head-y) init_task.o vmlinux.lds |
diff --git a/arch/unicore32/kernel/dma.c b/arch/unicore32/kernel/dma.c index ed2d4d78d9c..ae441bc3122 100644 --- a/arch/unicore32/kernel/dma.c +++ b/arch/unicore32/kernel/dma.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/errno.h> | 18 | #include <linux/errno.h> |
19 | #include <linux/io.h> | 19 | #include <linux/io.h> |
20 | 20 | ||
21 | #include <asm/system.h> | ||
21 | #include <asm/irq.h> | 22 | #include <asm/irq.h> |
22 | #include <mach/hardware.h> | 23 | #include <mach/hardware.h> |
23 | #include <mach/dma.h> | 24 | #include <mach/dma.h> |
diff --git a/arch/unicore32/kernel/entry.S b/arch/unicore32/kernel/entry.S index 581630d9144..00a259f9819 100644 --- a/arch/unicore32/kernel/entry.S +++ b/arch/unicore32/kernel/entry.S | |||
@@ -544,6 +544,8 @@ fast_work_pending: | |||
544 | work_pending: | 544 | work_pending: |
545 | cand.a r1, #_TIF_NEED_RESCHED | 545 | cand.a r1, #_TIF_NEED_RESCHED |
546 | bne work_resched | 546 | bne work_resched |
547 | cand.a r1, #_TIF_SIGPENDING|_TIF_NOTIFY_RESUME | ||
548 | beq no_work_pending | ||
547 | mov r0, sp @ 'regs' | 549 | mov r0, sp @ 'regs' |
548 | mov r2, why @ 'syscall' | 550 | mov r2, why @ 'syscall' |
549 | cand.a r1, #_TIF_SIGPENDING @ delivering a signal? | 551 | cand.a r1, #_TIF_SIGPENDING @ delivering a signal? |
@@ -573,16 +575,17 @@ ENDPROC(ret_to_user) | |||
573 | */ | 575 | */ |
574 | ENTRY(ret_from_fork) | 576 | ENTRY(ret_from_fork) |
575 | b.l schedule_tail | 577 | b.l schedule_tail |
578 | get_thread_info tsk | ||
579 | ldw r1, [tsk+], #TI_FLAGS @ check for syscall tracing | ||
580 | mov why, #1 | ||
581 | cand.a r1, #_TIF_SYSCALL_TRACE @ are we tracing syscalls? | ||
582 | beq ret_slow_syscall | ||
583 | mov r1, sp | ||
584 | mov r0, #1 @ trace exit [IP = 1] | ||
585 | b.l syscall_trace | ||
576 | b ret_slow_syscall | 586 | b ret_slow_syscall |
577 | ENDPROC(ret_from_fork) | 587 | ENDPROC(ret_from_fork) |
578 | 588 | ||
579 | ENTRY(ret_from_kernel_thread) | ||
580 | b.l schedule_tail | ||
581 | mov r0, r5 | ||
582 | adr lr, ret_slow_syscall | ||
583 | mov pc, r4 | ||
584 | ENDPROC(ret_from_kernel_thread) | ||
585 | |||
586 | /*============================================================================= | 589 | /*============================================================================= |
587 | * SWI handler | 590 | * SWI handler |
588 | *----------------------------------------------------------------------------- | 591 | *----------------------------------------------------------------------------- |
@@ -668,6 +671,17 @@ __cr_alignment: | |||
668 | #endif | 671 | #endif |
669 | .ltorg | 672 | .ltorg |
670 | 673 | ||
674 | ENTRY(sys_execve) | ||
675 | add r3, sp, #S_OFF | ||
676 | b __sys_execve | ||
677 | ENDPROC(sys_execve) | ||
678 | |||
679 | ENTRY(sys_clone) | ||
680 | add ip, sp, #S_OFF | ||
681 | stw ip, [sp+], #4 | ||
682 | b __sys_clone | ||
683 | ENDPROC(sys_clone) | ||
684 | |||
671 | ENTRY(sys_rt_sigreturn) | 685 | ENTRY(sys_rt_sigreturn) |
672 | add r0, sp, #S_OFF | 686 | add r0, sp, #S_OFF |
673 | mov why, #0 @ prevent syscall restart handling | 687 | mov why, #0 @ prevent syscall restart handling |
diff --git a/arch/unicore32/kernel/head.S b/arch/unicore32/kernel/head.S index e8f0b98c02e..8caf322e110 100644 --- a/arch/unicore32/kernel/head.S +++ b/arch/unicore32/kernel/head.S | |||
@@ -17,7 +17,7 @@ | |||
17 | #include <generated/asm-offsets.h> | 17 | #include <generated/asm-offsets.h> |
18 | #include <asm/memory.h> | 18 | #include <asm/memory.h> |
19 | #include <asm/thread_info.h> | 19 | #include <asm/thread_info.h> |
20 | #include <asm/hwdef-copro.h> | 20 | #include <asm/system.h> |
21 | #include <asm/pgtable-hwdef.h> | 21 | #include <asm/pgtable-hwdef.h> |
22 | 22 | ||
23 | #if (PHYS_OFFSET & 0x003fffff) | 23 | #if (PHYS_OFFSET & 0x003fffff) |
diff --git a/arch/unicore32/kernel/hibernate.c b/arch/unicore32/kernel/hibernate.c index d75ef8b6cb5..7d0f0b7983a 100644 --- a/arch/unicore32/kernel/hibernate.c +++ b/arch/unicore32/kernel/hibernate.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/suspend.h> | 15 | #include <linux/suspend.h> |
16 | #include <linux/bootmem.h> | 16 | #include <linux/bootmem.h> |
17 | 17 | ||
18 | #include <asm/system.h> | ||
18 | #include <asm/page.h> | 19 | #include <asm/page.h> |
19 | #include <asm/pgtable.h> | 20 | #include <asm/pgtable.h> |
20 | #include <asm/pgalloc.h> | 21 | #include <asm/pgalloc.h> |
diff --git a/arch/unicore32/kernel/irq.c b/arch/unicore32/kernel/irq.c index 0be5ccd7ccd..d4efa7d679f 100644 --- a/arch/unicore32/kernel/irq.c +++ b/arch/unicore32/kernel/irq.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/syscore_ops.h> | 26 | #include <linux/syscore_ops.h> |
27 | #include <linux/gpio.h> | 27 | #include <linux/gpio.h> |
28 | 28 | ||
29 | #include <asm/system.h> | ||
29 | #include <mach/hardware.h> | 30 | #include <mach/hardware.h> |
30 | 31 | ||
31 | #include "setup.h" | 32 | #include "setup.h" |
diff --git a/arch/unicore32/kernel/ksyms.c b/arch/unicore32/kernel/ksyms.c index d285d71cbe3..a8970809428 100644 --- a/arch/unicore32/kernel/ksyms.c +++ b/arch/unicore32/kernel/ksyms.c | |||
@@ -20,11 +20,12 @@ | |||
20 | #include <linux/io.h> | 20 | #include <linux/io.h> |
21 | 21 | ||
22 | #include <asm/checksum.h> | 22 | #include <asm/checksum.h> |
23 | #include <asm/system.h> | ||
23 | 24 | ||
24 | #include "ksyms.h" | 25 | #include "ksyms.h" |
25 | 26 | ||
26 | EXPORT_SYMBOL(find_next_zero_bit); | 27 | EXPORT_SYMBOL(__uc32_find_next_zero_bit); |
27 | EXPORT_SYMBOL(find_next_bit); | 28 | EXPORT_SYMBOL(__uc32_find_next_bit); |
28 | 29 | ||
29 | EXPORT_SYMBOL(__backtrace); | 30 | EXPORT_SYMBOL(__backtrace); |
30 | 31 | ||
diff --git a/arch/unicore32/kernel/module.c b/arch/unicore32/kernel/module.c index 16bd1495b93..8fbe8577f5e 100644 --- a/arch/unicore32/kernel/module.c +++ b/arch/unicore32/kernel/module.c | |||
@@ -27,6 +27,9 @@ void *module_alloc(unsigned long size) | |||
27 | struct vm_struct *area; | 27 | struct vm_struct *area; |
28 | 28 | ||
29 | size = PAGE_ALIGN(size); | 29 | size = PAGE_ALIGN(size); |
30 | if (!size) | ||
31 | return NULL; | ||
32 | |||
30 | area = __get_vm_area(size, VM_ALLOC, MODULES_VADDR, MODULES_END); | 33 | area = __get_vm_area(size, VM_ALLOC, MODULES_VADDR, MODULES_END); |
31 | if (!area) | 34 | if (!area) |
32 | return NULL; | 35 | return NULL; |
diff --git a/arch/unicore32/kernel/pci.c b/arch/unicore32/kernel/pci.c index ef69c0c8282..4892fbb54eb 100644 --- a/arch/unicore32/kernel/pci.c +++ b/arch/unicore32/kernel/pci.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/io.h> | 21 | #include <linux/io.h> |
22 | 22 | ||
23 | static int debug_pci; | 23 | static int debug_pci; |
24 | static int use_firmware; | ||
24 | 25 | ||
25 | #define CONFIG_CMD(bus, devfn, where) \ | 26 | #define CONFIG_CMD(bus, devfn, where) \ |
26 | (0x80000000 | (bus->number << 16) | (devfn << 8) | (where & ~3)) | 27 | (0x80000000 | (bus->number << 16) | (devfn << 8) | (where & ~3)) |
@@ -154,6 +155,14 @@ void __init puv3_pci_adjust_zones(unsigned long *zone_size, | |||
154 | zhole_size[0] = 0; | 155 | zhole_size[0] = 0; |
155 | } | 156 | } |
156 | 157 | ||
158 | void __devinit pcibios_update_irq(struct pci_dev *dev, int irq) | ||
159 | { | ||
160 | if (debug_pci) | ||
161 | printk(KERN_DEBUG "PCI: Assigning IRQ %02d to %s\n", | ||
162 | irq, pci_name(dev)); | ||
163 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); | ||
164 | } | ||
165 | |||
157 | /* | 166 | /* |
158 | * If the bus contains any of these devices, then we must not turn on | 167 | * If the bus contains any of these devices, then we must not turn on |
159 | * parity checking of any kind. | 168 | * parity checking of any kind. |
@@ -167,7 +176,7 @@ static inline int pdev_bad_for_parity(struct pci_dev *dev) | |||
167 | * pcibios_fixup_bus - Called after each bus is probed, | 176 | * pcibios_fixup_bus - Called after each bus is probed, |
168 | * but before its children are examined. | 177 | * but before its children are examined. |
169 | */ | 178 | */ |
170 | void pcibios_fixup_bus(struct pci_bus *bus) | 179 | void __devinit pcibios_fixup_bus(struct pci_bus *bus) |
171 | { | 180 | { |
172 | struct pci_dev *dev; | 181 | struct pci_dev *dev; |
173 | u16 features = PCI_COMMAND_SERR | 182 | u16 features = PCI_COMMAND_SERR |
@@ -250,7 +259,9 @@ void pcibios_fixup_bus(struct pci_bus *bus) | |||
250 | printk(KERN_INFO "PCI: bus%d: Fast back to back transfers %sabled\n", | 259 | printk(KERN_INFO "PCI: bus%d: Fast back to back transfers %sabled\n", |
251 | bus->number, (features & PCI_COMMAND_FAST_BACK) ? "en" : "dis"); | 260 | bus->number, (features & PCI_COMMAND_FAST_BACK) ? "en" : "dis"); |
252 | } | 261 | } |
262 | #ifdef CONFIG_HOTPLUG | ||
253 | EXPORT_SYMBOL(pcibios_fixup_bus); | 263 | EXPORT_SYMBOL(pcibios_fixup_bus); |
264 | #endif | ||
254 | 265 | ||
255 | static int __init pci_common_init(void) | 266 | static int __init pci_common_init(void) |
256 | { | 267 | { |
@@ -265,7 +276,7 @@ static int __init pci_common_init(void) | |||
265 | 276 | ||
266 | pci_fixup_irqs(pci_common_swizzle, pci_puv3_map_irq); | 277 | pci_fixup_irqs(pci_common_swizzle, pci_puv3_map_irq); |
267 | 278 | ||
268 | if (!pci_has_flag(PCI_PROBE_ONLY)) { | 279 | if (!use_firmware) { |
269 | /* | 280 | /* |
270 | * Size the bridge windows. | 281 | * Size the bridge windows. |
271 | */ | 282 | */ |
@@ -286,23 +297,18 @@ static int __init pci_common_init(void) | |||
286 | } | 297 | } |
287 | subsys_initcall(pci_common_init); | 298 | subsys_initcall(pci_common_init); |
288 | 299 | ||
289 | char * __init pcibios_setup(char *str) | 300 | char * __devinit pcibios_setup(char *str) |
290 | { | 301 | { |
291 | if (!strcmp(str, "debug")) { | 302 | if (!strcmp(str, "debug")) { |
292 | debug_pci = 1; | 303 | debug_pci = 1; |
293 | return NULL; | 304 | return NULL; |
294 | } else if (!strcmp(str, "firmware")) { | 305 | } else if (!strcmp(str, "firmware")) { |
295 | pci_add_flags(PCI_PROBE_ONLY); | 306 | use_firmware = 1; |
296 | return NULL; | 307 | return NULL; |
297 | } | 308 | } |
298 | return str; | 309 | return str; |
299 | } | 310 | } |
300 | 311 | ||
301 | void pcibios_set_master(struct pci_dev *dev) | ||
302 | { | ||
303 | /* No special bus mastering setup handling */ | ||
304 | } | ||
305 | |||
306 | /* | 312 | /* |
307 | * From arch/i386/kernel/pci-i386.c: | 313 | * From arch/i386/kernel/pci-i386.c: |
308 | * | 314 | * |
diff --git a/arch/unicore32/kernel/process.c b/arch/unicore32/kernel/process.c index 62bad9fed03..ba401df971e 100644 --- a/arch/unicore32/kernel/process.c +++ b/arch/unicore32/kernel/process.c | |||
@@ -34,6 +34,7 @@ | |||
34 | 34 | ||
35 | #include <asm/cacheflush.h> | 35 | #include <asm/cacheflush.h> |
36 | #include <asm/processor.h> | 36 | #include <asm/processor.h> |
37 | #include <asm/system.h> | ||
37 | #include <asm/stacktrace.h> | 38 | #include <asm/stacktrace.h> |
38 | 39 | ||
39 | #include "setup.h" | 40 | #include "setup.h" |
@@ -54,8 +55,7 @@ void cpu_idle(void) | |||
54 | { | 55 | { |
55 | /* endless idle loop with no priority at all */ | 56 | /* endless idle loop with no priority at all */ |
56 | while (1) { | 57 | while (1) { |
57 | tick_nohz_idle_enter(); | 58 | tick_nohz_stop_sched_tick(1); |
58 | rcu_idle_enter(); | ||
59 | while (!need_resched()) { | 59 | while (!need_resched()) { |
60 | local_irq_disable(); | 60 | local_irq_disable(); |
61 | stop_critical_timings(); | 61 | stop_critical_timings(); |
@@ -63,8 +63,7 @@ void cpu_idle(void) | |||
63 | local_irq_enable(); | 63 | local_irq_enable(); |
64 | start_critical_timings(); | 64 | start_critical_timings(); |
65 | } | 65 | } |
66 | rcu_idle_exit(); | 66 | tick_nohz_restart_sched_tick(); |
67 | tick_nohz_idle_exit(); | ||
68 | preempt_enable_no_resched(); | 67 | preempt_enable_no_resched(); |
69 | schedule(); | 68 | schedule(); |
70 | preempt_disable(); | 69 | preempt_disable(); |
@@ -258,32 +257,25 @@ void release_thread(struct task_struct *dead_task) | |||
258 | } | 257 | } |
259 | 258 | ||
260 | asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); | 259 | asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); |
261 | asmlinkage void ret_from_kernel_thread(void) __asm__("ret_from_kernel_thread"); | ||
262 | 260 | ||
263 | int | 261 | int |
264 | copy_thread(unsigned long clone_flags, unsigned long stack_start, | 262 | copy_thread(unsigned long clone_flags, unsigned long stack_start, |
265 | unsigned long stk_sz, struct task_struct *p) | 263 | unsigned long stk_sz, struct task_struct *p, struct pt_regs *regs) |
266 | { | 264 | { |
267 | struct thread_info *thread = task_thread_info(p); | 265 | struct thread_info *thread = task_thread_info(p); |
268 | struct pt_regs *childregs = task_pt_regs(p); | 266 | struct pt_regs *childregs = task_pt_regs(p); |
269 | 267 | ||
268 | *childregs = *regs; | ||
269 | childregs->UCreg_00 = 0; | ||
270 | childregs->UCreg_sp = stack_start; | ||
271 | |||
270 | memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save)); | 272 | memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save)); |
271 | thread->cpu_context.sp = (unsigned long)childregs; | 273 | thread->cpu_context.sp = (unsigned long)childregs; |
272 | if (unlikely(p->flags & PF_KTHREAD)) { | 274 | thread->cpu_context.pc = (unsigned long)ret_from_fork; |
273 | thread->cpu_context.pc = (unsigned long)ret_from_kernel_thread; | 275 | |
274 | thread->cpu_context.r4 = stack_start; | 276 | if (clone_flags & CLONE_SETTLS) |
275 | thread->cpu_context.r5 = stk_sz; | 277 | childregs->UCreg_16 = regs->UCreg_03; |
276 | memset(childregs, 0, sizeof(struct pt_regs)); | 278 | |
277 | } else { | ||
278 | thread->cpu_context.pc = (unsigned long)ret_from_fork; | ||
279 | *childregs = *current_pt_regs(); | ||
280 | childregs->UCreg_00 = 0; | ||
281 | if (stack_start) | ||
282 | childregs->UCreg_sp = stack_start; | ||
283 | |||
284 | if (clone_flags & CLONE_SETTLS) | ||
285 | childregs->UCreg_16 = childregs->UCreg_03; | ||
286 | } | ||
287 | return 0; | 279 | return 0; |
288 | } | 280 | } |
289 | 281 | ||
@@ -312,6 +304,42 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fp) | |||
312 | } | 304 | } |
313 | EXPORT_SYMBOL(dump_fpu); | 305 | EXPORT_SYMBOL(dump_fpu); |
314 | 306 | ||
307 | /* | ||
308 | * Shuffle the argument into the correct register before calling the | ||
309 | * thread function. r1 is the thread argument, r2 is the pointer to | ||
310 | * the thread function, and r3 points to the exit function. | ||
311 | */ | ||
312 | asm(".pushsection .text\n" | ||
313 | " .align\n" | ||
314 | " .type kernel_thread_helper, #function\n" | ||
315 | "kernel_thread_helper:\n" | ||
316 | " mov.a asr, r7\n" | ||
317 | " mov r0, r4\n" | ||
318 | " mov lr, r6\n" | ||
319 | " mov pc, r5\n" | ||
320 | " .size kernel_thread_helper, . - kernel_thread_helper\n" | ||
321 | " .popsection"); | ||
322 | |||
323 | /* | ||
324 | * Create a kernel thread. | ||
325 | */ | ||
326 | pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) | ||
327 | { | ||
328 | struct pt_regs regs; | ||
329 | |||
330 | memset(®s, 0, sizeof(regs)); | ||
331 | |||
332 | regs.UCreg_04 = (unsigned long)arg; | ||
333 | regs.UCreg_05 = (unsigned long)fn; | ||
334 | regs.UCreg_06 = (unsigned long)do_exit; | ||
335 | regs.UCreg_07 = PRIV_MODE; | ||
336 | regs.UCreg_pc = (unsigned long)kernel_thread_helper; | ||
337 | regs.UCreg_asr = regs.UCreg_07 | PSR_I_BIT; | ||
338 | |||
339 | return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); | ||
340 | } | ||
341 | EXPORT_SYMBOL(kernel_thread); | ||
342 | |||
315 | unsigned long get_wchan(struct task_struct *p) | 343 | unsigned long get_wchan(struct task_struct *p) |
316 | { | 344 | { |
317 | struct stackframe frame; | 345 | struct stackframe frame; |
@@ -351,7 +379,7 @@ int vectors_user_mapping(void) | |||
351 | return install_special_mapping(mm, 0xffff0000, PAGE_SIZE, | 379 | return install_special_mapping(mm, 0xffff0000, PAGE_SIZE, |
352 | VM_READ | VM_EXEC | | 380 | VM_READ | VM_EXEC | |
353 | VM_MAYREAD | VM_MAYEXEC | | 381 | VM_MAYREAD | VM_MAYEXEC | |
354 | VM_DONTEXPAND | VM_DONTDUMP, | 382 | VM_ALWAYSDUMP | VM_RESERVED, |
355 | NULL); | 383 | NULL); |
356 | } | 384 | } |
357 | 385 | ||
diff --git a/arch/unicore32/kernel/puv3-core.c b/arch/unicore32/kernel/puv3-core.c index 254adeecc61..1a505a78776 100644 --- a/arch/unicore32/kernel/puv3-core.c +++ b/arch/unicore32/kernel/puv3-core.c | |||
@@ -13,6 +13,7 @@ | |||
13 | 13 | ||
14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | #include <linux/device.h> | 15 | #include <linux/device.h> |
16 | #include <linux/sysdev.h> | ||
16 | #include <linux/amba/bus.h> | 17 | #include <linux/amba/bus.h> |
17 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
18 | #include <linux/io.h> | 19 | #include <linux/io.h> |
diff --git a/arch/unicore32/kernel/puv3-nb0916.c b/arch/unicore32/kernel/puv3-nb0916.c index 181108b8ecc..e731c561ed4 100644 --- a/arch/unicore32/kernel/puv3-nb0916.c +++ b/arch/unicore32/kernel/puv3-nb0916.c | |||
@@ -13,6 +13,7 @@ | |||
13 | 13 | ||
14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | #include <linux/device.h> | 15 | #include <linux/device.h> |
16 | #include <linux/sysdev.h> | ||
16 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
17 | #include <linux/mtd/physmap.h> | 18 | #include <linux/mtd/physmap.h> |
18 | #include <linux/io.h> | 19 | #include <linux/io.h> |
@@ -123,7 +124,7 @@ int __init mach_nb0916_init(void) | |||
123 | 124 | ||
124 | if (request_irq(gpio_to_irq(GPI_LCD_CASE_OFF), | 125 | if (request_irq(gpio_to_irq(GPI_LCD_CASE_OFF), |
125 | &nb0916_lcdcaseoff_handler, | 126 | &nb0916_lcdcaseoff_handler, |
126 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, | 127 | IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, |
127 | "NB0916 lcd case off", NULL) < 0) { | 128 | "NB0916 lcd case off", NULL) < 0) { |
128 | 129 | ||
129 | printk(KERN_DEBUG "LCD-Case-OFF IRQ %d not available\n", | 130 | printk(KERN_DEBUG "LCD-Case-OFF IRQ %d not available\n", |
@@ -131,7 +132,7 @@ int __init mach_nb0916_init(void) | |||
131 | } | 132 | } |
132 | 133 | ||
133 | if (request_irq(gpio_to_irq(GPI_OTP_INT), &nb0916_overheat_handler, | 134 | if (request_irq(gpio_to_irq(GPI_OTP_INT), &nb0916_overheat_handler, |
134 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, | 135 | IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, |
135 | "NB0916 overheating protection", NULL) < 0) { | 136 | "NB0916 overheating protection", NULL) < 0) { |
136 | 137 | ||
137 | printk(KERN_DEBUG "Overheating Protection IRQ %d not available\n", | 138 | printk(KERN_DEBUG "Overheating Protection IRQ %d not available\n", |
diff --git a/arch/unicore32/kernel/setup.c b/arch/unicore32/kernel/setup.c index 87adbf5ebfe..471b6bca8da 100644 --- a/arch/unicore32/kernel/setup.c +++ b/arch/unicore32/kernel/setup.c | |||
@@ -37,7 +37,6 @@ | |||
37 | #include <asm/cacheflush.h> | 37 | #include <asm/cacheflush.h> |
38 | #include <asm/tlbflush.h> | 38 | #include <asm/tlbflush.h> |
39 | #include <asm/traps.h> | 39 | #include <asm/traps.h> |
40 | #include <asm/memblock.h> | ||
41 | 40 | ||
42 | #include "setup.h" | 41 | #include "setup.h" |
43 | 42 | ||
@@ -65,7 +64,7 @@ static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE; | |||
65 | */ | 64 | */ |
66 | static struct resource mem_res[] = { | 65 | static struct resource mem_res[] = { |
67 | { | 66 | { |
68 | .name = "Kernel code", | 67 | .name = "Kernel text", |
69 | .start = 0, | 68 | .start = 0, |
70 | .end = 0, | 69 | .end = 0, |
71 | .flags = IORESOURCE_MEM | 70 | .flags = IORESOURCE_MEM |
diff --git a/arch/unicore32/kernel/setup.h b/arch/unicore32/kernel/setup.h index 30f749da8f7..dcd1306eb5c 100644 --- a/arch/unicore32/kernel/setup.h +++ b/arch/unicore32/kernel/setup.h | |||
@@ -12,11 +12,8 @@ | |||
12 | #ifndef __UNICORE_KERNEL_SETUP_H__ | 12 | #ifndef __UNICORE_KERNEL_SETUP_H__ |
13 | #define __UNICORE_KERNEL_SETUP_H__ | 13 | #define __UNICORE_KERNEL_SETUP_H__ |
14 | 14 | ||
15 | #include <asm/hwdef-copro.h> | ||
16 | |||
17 | extern void paging_init(void); | 15 | extern void paging_init(void); |
18 | extern void puv3_core_init(void); | 16 | extern void puv3_core_init(void); |
19 | extern void cpu_init(void); | ||
20 | 17 | ||
21 | extern void puv3_ps2_init(void); | 18 | extern void puv3_ps2_init(void); |
22 | extern void pci_puv3_preinit(void); | 19 | extern void pci_puv3_preinit(void); |
@@ -30,10 +27,4 @@ extern char __vectors_start[], __vectors_end[]; | |||
30 | extern void kernel_thread_helper(void); | 27 | extern void kernel_thread_helper(void); |
31 | 28 | ||
32 | extern void __init early_signal_init(void); | 29 | extern void __init early_signal_init(void); |
33 | |||
34 | extern asmlinkage void __backtrace(void); | ||
35 | extern asmlinkage void c_backtrace(unsigned long fp, int pmode); | ||
36 | |||
37 | extern void __show_regs(struct pt_regs *); | ||
38 | |||
39 | #endif | 30 | #endif |
diff --git a/arch/unicore32/kernel/signal.c b/arch/unicore32/kernel/signal.c index b8b2ffd774d..b163fca5678 100644 --- a/arch/unicore32/kernel/signal.c +++ b/arch/unicore32/kernel/signal.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/errno.h> | 12 | #include <linux/errno.h> |
13 | #include <linux/signal.h> | 13 | #include <linux/signal.h> |
14 | #include <linux/personality.h> | 14 | #include <linux/personality.h> |
15 | #include <linux/freezer.h> | ||
15 | #include <linux/uaccess.h> | 16 | #include <linux/uaccess.h> |
16 | #include <linux/tracehook.h> | 17 | #include <linux/tracehook.h> |
17 | #include <linux/elf.h> | 18 | #include <linux/elf.h> |
@@ -20,6 +21,8 @@ | |||
20 | #include <asm/cacheflush.h> | 21 | #include <asm/cacheflush.h> |
21 | #include <asm/ucontext.h> | 22 | #include <asm/ucontext.h> |
22 | 23 | ||
24 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) | ||
25 | |||
23 | /* | 26 | /* |
24 | * For UniCore syscalls, we encode the syscall number into the instruction. | 27 | * For UniCore syscalls, we encode the syscall number into the instruction. |
25 | */ | 28 | */ |
@@ -58,8 +61,13 @@ static int restore_sigframe(struct pt_regs *regs, struct sigframe __user *sf) | |||
58 | int err; | 61 | int err; |
59 | 62 | ||
60 | err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set)); | 63 | err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set)); |
61 | if (err == 0) | 64 | if (err == 0) { |
62 | set_current_blocked(&set); | 65 | sigdelsetmask(&set, ~_BLOCKABLE); |
66 | spin_lock_irq(¤t->sighand->siglock); | ||
67 | current->blocked = set; | ||
68 | recalc_sigpending(); | ||
69 | spin_unlock_irq(¤t->sighand->siglock); | ||
70 | } | ||
63 | 71 | ||
64 | err |= __get_user(regs->UCreg_00, &sf->uc.uc_mcontext.regs.UCreg_00); | 72 | err |= __get_user(regs->UCreg_00, &sf->uc.uc_mcontext.regs.UCreg_00); |
65 | err |= __get_user(regs->UCreg_01, &sf->uc.uc_mcontext.regs.UCreg_01); | 73 | err |= __get_user(regs->UCreg_01, &sf->uc.uc_mcontext.regs.UCreg_01); |
@@ -307,12 +315,12 @@ static inline void setup_syscall_restart(struct pt_regs *regs) | |||
307 | /* | 315 | /* |
308 | * OK, we're invoking a handler | 316 | * OK, we're invoking a handler |
309 | */ | 317 | */ |
310 | static void handle_signal(unsigned long sig, struct k_sigaction *ka, | 318 | static int handle_signal(unsigned long sig, struct k_sigaction *ka, |
311 | siginfo_t *info, struct pt_regs *regs, int syscall) | 319 | siginfo_t *info, sigset_t *oldset, |
320 | struct pt_regs *regs, int syscall) | ||
312 | { | 321 | { |
313 | struct thread_info *thread = current_thread_info(); | 322 | struct thread_info *thread = current_thread_info(); |
314 | struct task_struct *tsk = current; | 323 | struct task_struct *tsk = current; |
315 | sigset_t *oldset = sigmask_to_save(); | ||
316 | int usig = sig; | 324 | int usig = sig; |
317 | int ret; | 325 | int ret; |
318 | 326 | ||
@@ -358,10 +366,21 @@ static void handle_signal(unsigned long sig, struct k_sigaction *ka, | |||
358 | 366 | ||
359 | if (ret != 0) { | 367 | if (ret != 0) { |
360 | force_sigsegv(sig, tsk); | 368 | force_sigsegv(sig, tsk); |
361 | return; | 369 | return ret; |
362 | } | 370 | } |
363 | 371 | ||
364 | signal_delivered(sig, info, ka, regs, 0); | 372 | /* |
373 | * Block the signal if we were successful. | ||
374 | */ | ||
375 | spin_lock_irq(&tsk->sighand->siglock); | ||
376 | sigorsets(&tsk->blocked, &tsk->blocked, | ||
377 | &ka->sa.sa_mask); | ||
378 | if (!(ka->sa.sa_flags & SA_NODEFER)) | ||
379 | sigaddset(&tsk->blocked, sig); | ||
380 | recalc_sigpending(); | ||
381 | spin_unlock_irq(&tsk->sighand->siglock); | ||
382 | |||
383 | return 0; | ||
365 | } | 384 | } |
366 | 385 | ||
367 | /* | 386 | /* |
@@ -388,12 +407,32 @@ static void do_signal(struct pt_regs *regs, int syscall) | |||
388 | if (!user_mode(regs)) | 407 | if (!user_mode(regs)) |
389 | return; | 408 | return; |
390 | 409 | ||
410 | if (try_to_freeze()) | ||
411 | goto no_signal; | ||
412 | |||
391 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); | 413 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); |
392 | if (signr > 0) { | 414 | if (signr > 0) { |
393 | handle_signal(signr, &ka, &info, regs, syscall); | 415 | sigset_t *oldset; |
416 | |||
417 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) | ||
418 | oldset = ¤t->saved_sigmask; | ||
419 | else | ||
420 | oldset = ¤t->blocked; | ||
421 | if (handle_signal(signr, &ka, &info, oldset, regs, syscall) | ||
422 | == 0) { | ||
423 | /* | ||
424 | * A signal was successfully delivered; the saved | ||
425 | * sigmask will have been stored in the signal frame, | ||
426 | * and will be restored by sigreturn, so we can simply | ||
427 | * clear the TIF_RESTORE_SIGMASK flag. | ||
428 | */ | ||
429 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) | ||
430 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
431 | } | ||
394 | return; | 432 | return; |
395 | } | 433 | } |
396 | 434 | ||
435 | no_signal: | ||
397 | /* | 436 | /* |
398 | * No signal to deliver to the process - restart the syscall. | 437 | * No signal to deliver to the process - restart the syscall. |
399 | */ | 438 | */ |
@@ -416,11 +455,15 @@ static void do_signal(struct pt_regs *regs, int syscall) | |||
416 | regs->UCreg_00 == -ERESTARTNOINTR) { | 455 | regs->UCreg_00 == -ERESTARTNOINTR) { |
417 | setup_syscall_restart(regs); | 456 | setup_syscall_restart(regs); |
418 | } | 457 | } |
458 | |||
459 | /* If there's no signal to deliver, we just put the saved | ||
460 | * sigmask back. | ||
461 | */ | ||
462 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) { | ||
463 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
464 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); | ||
465 | } | ||
419 | } | 466 | } |
420 | /* If there's no signal to deliver, we just put the saved | ||
421 | * sigmask back. | ||
422 | */ | ||
423 | restore_saved_sigmask(); | ||
424 | } | 467 | } |
425 | 468 | ||
426 | asmlinkage void do_notify_resume(struct pt_regs *regs, | 469 | asmlinkage void do_notify_resume(struct pt_regs *regs, |
@@ -432,6 +475,8 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, | |||
432 | if (thread_flags & _TIF_NOTIFY_RESUME) { | 475 | if (thread_flags & _TIF_NOTIFY_RESUME) { |
433 | clear_thread_flag(TIF_NOTIFY_RESUME); | 476 | clear_thread_flag(TIF_NOTIFY_RESUME); |
434 | tracehook_notify_resume(regs); | 477 | tracehook_notify_resume(regs); |
478 | if (current->replacement_session_keyring) | ||
479 | key_replace_session_keyring(); | ||
435 | } | 480 | } |
436 | } | 481 | } |
437 | 482 | ||
diff --git a/arch/unicore32/kernel/sys.c b/arch/unicore32/kernel/sys.c index cfe79c9529b..3afe60a39ac 100644 --- a/arch/unicore32/kernel/sys.c +++ b/arch/unicore32/kernel/sys.c | |||
@@ -28,6 +28,84 @@ | |||
28 | #include <asm/syscalls.h> | 28 | #include <asm/syscalls.h> |
29 | #include <asm/cacheflush.h> | 29 | #include <asm/cacheflush.h> |
30 | 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(®s, 0, sizeof(struct pt_regs)); | ||
74 | ret = do_execve(filename, | ||
75 | (const char __user *const __user *)argv, | ||
76 | (const char __user *const __user *)envp, ®s); | ||
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" (®s), | ||
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 | |||
31 | /* Note: used by the compat code even in 64-bit Linux. */ | 109 | /* Note: used by the compat code even in 64-bit Linux. */ |
32 | SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len, | 110 | SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len, |
33 | unsigned long, prot, unsigned long, flags, | 111 | unsigned long, prot, unsigned long, flags, |
diff --git a/arch/unicore32/kernel/time.c b/arch/unicore32/kernel/time.c index d3824b2ff64..080710c0924 100644 --- a/arch/unicore32/kernel/time.c +++ b/arch/unicore32/kernel/time.c | |||
@@ -86,7 +86,7 @@ static struct clocksource cksrc_puv3_oscr = { | |||
86 | 86 | ||
87 | static struct irqaction puv3_timer_irq = { | 87 | static struct irqaction puv3_timer_irq = { |
88 | .name = "ost0", | 88 | .name = "ost0", |
89 | .flags = IRQF_TIMER | IRQF_IRQPOLL, | 89 | .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, |
90 | .handler = puv3_ost0_interrupt, | 90 | .handler = puv3_ost0_interrupt, |
91 | .dev_id = &ckevt_puv3_osmr0, | 91 | .dev_id = &ckevt_puv3_osmr0, |
92 | }; | 92 | }; |
diff --git a/arch/unicore32/kernel/traps.c b/arch/unicore32/kernel/traps.c index 2054f0d4db1..b9a26465e72 100644 --- a/arch/unicore32/kernel/traps.c +++ b/arch/unicore32/kernel/traps.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/unistd.h> | 26 | #include <linux/unistd.h> |
27 | 27 | ||
28 | #include <asm/cacheflush.h> | 28 | #include <asm/cacheflush.h> |
29 | #include <asm/system.h> | ||
29 | #include <asm/traps.h> | 30 | #include <asm/traps.h> |
30 | 31 | ||
31 | #include "setup.h" | 32 | #include "setup.h" |