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/parisc/kernel | |
parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) |
Patched in Tegra support.
Diffstat (limited to 'arch/parisc/kernel')
26 files changed, 674 insertions, 187 deletions
diff --git a/arch/parisc/kernel/Makefile b/arch/parisc/kernel/Makefile index 66ee3f12df5..67db0722e6c 100644 --- a/arch/parisc/kernel/Makefile +++ b/arch/parisc/kernel/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | # Makefile for arch/parisc/kernel | 2 | # Makefile for arch/parisc/kernel |
3 | # | 3 | # |
4 | 4 | ||
5 | extra-y := head.o vmlinux.lds | 5 | extra-y := init_task.o head.o vmlinux.lds |
6 | 6 | ||
7 | obj-y := cache.o pacache.o setup.o traps.o time.o irq.o \ | 7 | obj-y := cache.o pacache.o setup.o traps.o time.o irq.o \ |
8 | pa7300lc.o syscall.o entry.o sys_parisc.o firmware.o \ | 8 | pa7300lc.o syscall.o entry.o sys_parisc.o firmware.o \ |
diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c index 48e16dc2010..83335f3da5f 100644 --- a/arch/parisc/kernel/cache.c +++ b/arch/parisc/kernel/cache.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <asm/cache.h> | 22 | #include <asm/cache.h> |
23 | #include <asm/cacheflush.h> | 23 | #include <asm/cacheflush.h> |
24 | #include <asm/tlbflush.h> | 24 | #include <asm/tlbflush.h> |
25 | #include <asm/system.h> | ||
25 | #include <asm/page.h> | 26 | #include <asm/page.h> |
26 | #include <asm/pgalloc.h> | 27 | #include <asm/pgalloc.h> |
27 | #include <asm/processor.h> | 28 | #include <asm/processor.h> |
@@ -276,6 +277,7 @@ void flush_dcache_page(struct page *page) | |||
276 | { | 277 | { |
277 | struct address_space *mapping = page_mapping(page); | 278 | struct address_space *mapping = page_mapping(page); |
278 | struct vm_area_struct *mpnt; | 279 | struct vm_area_struct *mpnt; |
280 | struct prio_tree_iter iter; | ||
279 | unsigned long offset; | 281 | unsigned long offset; |
280 | unsigned long addr, old_addr = 0; | 282 | unsigned long addr, old_addr = 0; |
281 | pgoff_t pgoff; | 283 | pgoff_t pgoff; |
@@ -298,7 +300,7 @@ void flush_dcache_page(struct page *page) | |||
298 | * to flush one address here for them all to become coherent */ | 300 | * to flush one address here for them all to become coherent */ |
299 | 301 | ||
300 | flush_dcache_mmap_lock(mapping); | 302 | flush_dcache_mmap_lock(mapping); |
301 | vma_interval_tree_foreach(mpnt, &mapping->i_mmap, pgoff, pgoff) { | 303 | vma_prio_tree_foreach(mpnt, &iter, &mapping->i_mmap, pgoff, pgoff) { |
302 | offset = (pgoff - mpnt->vm_pgoff) << PAGE_SHIFT; | 304 | offset = (pgoff - mpnt->vm_pgoff) << PAGE_SHIFT; |
303 | addr = mpnt->vm_start + offset; | 305 | addr = mpnt->vm_start + offset; |
304 | 306 | ||
diff --git a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c index 5709c5e59be..994bcd98090 100644 --- a/arch/parisc/kernel/drivers.c +++ b/arch/parisc/kernel/drivers.c | |||
@@ -33,7 +33,6 @@ | |||
33 | #include <linux/pci.h> | 33 | #include <linux/pci.h> |
34 | #include <linux/spinlock.h> | 34 | #include <linux/spinlock.h> |
35 | #include <linux/string.h> | 35 | #include <linux/string.h> |
36 | #include <linux/export.h> | ||
37 | #include <asm/hardware.h> | 36 | #include <asm/hardware.h> |
38 | #include <asm/io.h> | 37 | #include <asm/io.h> |
39 | #include <asm/pdc.h> | 38 | #include <asm/pdc.h> |
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index bfb44247d7a..6f059443914 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S | |||
@@ -552,7 +552,7 @@ | |||
552 | * entry (identifying the physical page) and %r23 up with | 552 | * entry (identifying the physical page) and %r23 up with |
553 | * the from tlb entry (or nothing if only a to entry---for | 553 | * the from tlb entry (or nothing if only a to entry---for |
554 | * clear_user_page_asm) */ | 554 | * clear_user_page_asm) */ |
555 | .macro do_alias spc,tmp,tmp1,va,pte,prot,fault,patype | 555 | .macro do_alias spc,tmp,tmp1,va,pte,prot,fault |
556 | cmpib,COND(<>),n 0,\spc,\fault | 556 | cmpib,COND(<>),n 0,\spc,\fault |
557 | ldil L%(TMPALIAS_MAP_START),\tmp | 557 | ldil L%(TMPALIAS_MAP_START),\tmp |
558 | #if defined(CONFIG_64BIT) && (TMPALIAS_MAP_START >= 0x80000000) | 558 | #if defined(CONFIG_64BIT) && (TMPALIAS_MAP_START >= 0x80000000) |
@@ -581,15 +581,7 @@ | |||
581 | */ | 581 | */ |
582 | cmpiclr,= 0x01,\tmp,%r0 | 582 | cmpiclr,= 0x01,\tmp,%r0 |
583 | ldi (_PAGE_DIRTY|_PAGE_READ|_PAGE_WRITE),\prot | 583 | ldi (_PAGE_DIRTY|_PAGE_READ|_PAGE_WRITE),\prot |
584 | .ifc \patype,20 | ||
585 | depd,z \prot,8,7,\prot | 584 | depd,z \prot,8,7,\prot |
586 | .else | ||
587 | .ifc \patype,11 | ||
588 | depw,z \prot,8,7,\prot | ||
589 | .else | ||
590 | .error "undefined PA type to do_alias" | ||
591 | .endif | ||
592 | .endif | ||
593 | /* | 585 | /* |
594 | * OK, it is in the temp alias region, check whether "from" or "to". | 586 | * OK, it is in the temp alias region, check whether "from" or "to". |
595 | * Check "subtle" note in pacache.S re: r23/r26. | 587 | * Check "subtle" note in pacache.S re: r23/r26. |
@@ -708,9 +700,59 @@ ENTRY(end_fault_vector) | |||
708 | .import do_cpu_irq_mask,code | 700 | .import do_cpu_irq_mask,code |
709 | 701 | ||
710 | /* | 702 | /* |
703 | * r26 = function to be called | ||
704 | * r25 = argument to pass in | ||
705 | * r24 = flags for do_fork() | ||
706 | * | ||
707 | * Kernel threads don't ever return, so they don't need | ||
708 | * a true register context. We just save away the arguments | ||
709 | * for copy_thread/ret_ to properly set up the child. | ||
710 | */ | ||
711 | |||
712 | #define CLONE_VM 0x100 /* Must agree with <linux/sched.h> */ | ||
713 | #define CLONE_UNTRACED 0x00800000 | ||
714 | |||
715 | .import do_fork | ||
716 | ENTRY(__kernel_thread) | ||
717 | STREG %r2, -RP_OFFSET(%r30) | ||
718 | |||
719 | copy %r30, %r1 | ||
720 | ldo PT_SZ_ALGN(%r30),%r30 | ||
721 | #ifdef CONFIG_64BIT | ||
722 | /* Yo, function pointers in wide mode are little structs... -PB */ | ||
723 | ldd 24(%r26), %r2 | ||
724 | STREG %r2, PT_GR27(%r1) /* Store childs %dp */ | ||
725 | ldd 16(%r26), %r26 | ||
726 | |||
727 | STREG %r22, PT_GR22(%r1) /* save r22 (arg5) */ | ||
728 | copy %r0, %r22 /* user_tid */ | ||
729 | #endif | ||
730 | STREG %r26, PT_GR26(%r1) /* Store function & argument for child */ | ||
731 | STREG %r25, PT_GR25(%r1) | ||
732 | ldil L%CLONE_UNTRACED, %r26 | ||
733 | ldo CLONE_VM(%r26), %r26 /* Force CLONE_VM since only init_mm */ | ||
734 | or %r26, %r24, %r26 /* will have kernel mappings. */ | ||
735 | ldi 1, %r25 /* stack_start, signals kernel thread */ | ||
736 | stw %r0, -52(%r30) /* user_tid */ | ||
737 | #ifdef CONFIG_64BIT | ||
738 | ldo -16(%r30),%r29 /* Reference param save area */ | ||
739 | #endif | ||
740 | BL do_fork, %r2 | ||
741 | copy %r1, %r24 /* pt_regs */ | ||
742 | |||
743 | /* Parent Returns here */ | ||
744 | |||
745 | LDREG -PT_SZ_ALGN-RP_OFFSET(%r30), %r2 | ||
746 | ldo -PT_SZ_ALGN(%r30), %r30 | ||
747 | bv %r0(%r2) | ||
748 | nop | ||
749 | ENDPROC(__kernel_thread) | ||
750 | |||
751 | /* | ||
711 | * Child Returns here | 752 | * Child Returns here |
712 | * | 753 | * |
713 | * copy_thread moved args into task save area. | 754 | * copy_thread moved args from temp save area set up above |
755 | * into task save area. | ||
714 | */ | 756 | */ |
715 | 757 | ||
716 | ENTRY(ret_from_kernel_thread) | 758 | ENTRY(ret_from_kernel_thread) |
@@ -719,18 +761,52 @@ ENTRY(ret_from_kernel_thread) | |||
719 | BL schedule_tail, %r2 | 761 | BL schedule_tail, %r2 |
720 | nop | 762 | nop |
721 | 763 | ||
722 | LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1 | 764 | LDREG TI_TASK-THREAD_SZ_ALGN(%r30), %r1 |
723 | LDREG TASK_PT_GR25(%r1), %r26 | 765 | LDREG TASK_PT_GR25(%r1), %r26 |
724 | #ifdef CONFIG_64BIT | 766 | #ifdef CONFIG_64BIT |
725 | LDREG TASK_PT_GR27(%r1), %r27 | 767 | LDREG TASK_PT_GR27(%r1), %r27 |
768 | LDREG TASK_PT_GR22(%r1), %r22 | ||
726 | #endif | 769 | #endif |
727 | LDREG TASK_PT_GR26(%r1), %r1 | 770 | LDREG TASK_PT_GR26(%r1), %r1 |
728 | ble 0(%sr7, %r1) | 771 | ble 0(%sr7, %r1) |
729 | copy %r31, %r2 | 772 | copy %r31, %r2 |
730 | b finish_child_return | 773 | |
731 | nop | 774 | #ifdef CONFIG_64BIT |
775 | ldo -16(%r30),%r29 /* Reference param save area */ | ||
776 | loadgp /* Thread could have been in a module */ | ||
777 | #endif | ||
778 | #ifndef CONFIG_64BIT | ||
779 | b sys_exit | ||
780 | #else | ||
781 | load32 sys_exit, %r1 | ||
782 | bv %r0(%r1) | ||
783 | #endif | ||
784 | ldi 0, %r26 | ||
732 | ENDPROC(ret_from_kernel_thread) | 785 | ENDPROC(ret_from_kernel_thread) |
733 | 786 | ||
787 | .import sys_execve, code | ||
788 | ENTRY(__execve) | ||
789 | copy %r2, %r15 | ||
790 | copy %r30, %r16 | ||
791 | ldo PT_SZ_ALGN(%r30), %r30 | ||
792 | STREG %r26, PT_GR26(%r16) | ||
793 | STREG %r25, PT_GR25(%r16) | ||
794 | STREG %r24, PT_GR24(%r16) | ||
795 | #ifdef CONFIG_64BIT | ||
796 | ldo -16(%r30),%r29 /* Reference param save area */ | ||
797 | #endif | ||
798 | BL sys_execve, %r2 | ||
799 | copy %r16, %r26 | ||
800 | |||
801 | cmpib,=,n 0,%r28,intr_return /* forward */ | ||
802 | |||
803 | /* yes, this will trap and die. */ | ||
804 | copy %r15, %r2 | ||
805 | copy %r16, %r30 | ||
806 | bv %r0(%r2) | ||
807 | nop | ||
808 | ENDPROC(__execve) | ||
809 | |||
734 | 810 | ||
735 | /* | 811 | /* |
736 | * struct task_struct *_switch_to(struct task_struct *prev, | 812 | * struct task_struct *_switch_to(struct task_struct *prev, |
@@ -840,7 +916,7 @@ intr_check_sig: | |||
840 | /* As above */ | 916 | /* As above */ |
841 | mfctl %cr30,%r1 | 917 | mfctl %cr30,%r1 |
842 | LDREG TI_FLAGS(%r1),%r19 | 918 | LDREG TI_FLAGS(%r1),%r19 |
843 | ldi (_TIF_SIGPENDING|_TIF_NOTIFY_RESUME), %r20 | 919 | ldi (_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK|_TIF_NOTIFY_RESUME), %r20 |
844 | and,COND(<>) %r19, %r20, %r0 | 920 | and,COND(<>) %r19, %r20, %r0 |
845 | b,n intr_restore /* skip past if we've nothing to do */ | 921 | b,n intr_restore /* skip past if we've nothing to do */ |
846 | 922 | ||
@@ -1109,7 +1185,7 @@ dtlb_miss_20w: | |||
1109 | nop | 1185 | nop |
1110 | 1186 | ||
1111 | dtlb_check_alias_20w: | 1187 | dtlb_check_alias_20w: |
1112 | do_alias spc,t0,t1,va,pte,prot,dtlb_fault,20 | 1188 | do_alias spc,t0,t1,va,pte,prot,dtlb_fault |
1113 | 1189 | ||
1114 | idtlbt pte,prot | 1190 | idtlbt pte,prot |
1115 | 1191 | ||
@@ -1133,7 +1209,7 @@ nadtlb_miss_20w: | |||
1133 | nop | 1209 | nop |
1134 | 1210 | ||
1135 | nadtlb_check_alias_20w: | 1211 | nadtlb_check_alias_20w: |
1136 | do_alias spc,t0,t1,va,pte,prot,nadtlb_emulate,20 | 1212 | do_alias spc,t0,t1,va,pte,prot,nadtlb_emulate |
1137 | 1213 | ||
1138 | idtlbt pte,prot | 1214 | idtlbt pte,prot |
1139 | 1215 | ||
@@ -1165,7 +1241,7 @@ dtlb_miss_11: | |||
1165 | nop | 1241 | nop |
1166 | 1242 | ||
1167 | dtlb_check_alias_11: | 1243 | dtlb_check_alias_11: |
1168 | do_alias spc,t0,t1,va,pte,prot,dtlb_fault,11 | 1244 | do_alias spc,t0,t1,va,pte,prot,dtlb_fault |
1169 | 1245 | ||
1170 | idtlba pte,(va) | 1246 | idtlba pte,(va) |
1171 | idtlbp prot,(va) | 1247 | idtlbp prot,(va) |
@@ -1197,7 +1273,7 @@ nadtlb_miss_11: | |||
1197 | nop | 1273 | nop |
1198 | 1274 | ||
1199 | nadtlb_check_alias_11: | 1275 | nadtlb_check_alias_11: |
1200 | do_alias spc,t0,t1,va,pte,prot,nadtlb_emulate,11 | 1276 | do_alias spc,t0,t1,va,pte,prot,nadtlb_emulate |
1201 | 1277 | ||
1202 | idtlba pte,(va) | 1278 | idtlba pte,(va) |
1203 | idtlbp prot,(va) | 1279 | idtlbp prot,(va) |
@@ -1224,7 +1300,7 @@ dtlb_miss_20: | |||
1224 | nop | 1300 | nop |
1225 | 1301 | ||
1226 | dtlb_check_alias_20: | 1302 | dtlb_check_alias_20: |
1227 | do_alias spc,t0,t1,va,pte,prot,dtlb_fault,20 | 1303 | do_alias spc,t0,t1,va,pte,prot,dtlb_fault |
1228 | 1304 | ||
1229 | idtlbt pte,prot | 1305 | idtlbt pte,prot |
1230 | 1306 | ||
@@ -1250,7 +1326,7 @@ nadtlb_miss_20: | |||
1250 | nop | 1326 | nop |
1251 | 1327 | ||
1252 | nadtlb_check_alias_20: | 1328 | nadtlb_check_alias_20: |
1253 | do_alias spc,t0,t1,va,pte,prot,nadtlb_emulate,20 | 1329 | do_alias spc,t0,t1,va,pte,prot,nadtlb_emulate |
1254 | 1330 | ||
1255 | idtlbt pte,prot | 1331 | idtlbt pte,prot |
1256 | 1332 | ||
@@ -1377,7 +1453,7 @@ naitlb_miss_20w: | |||
1377 | nop | 1453 | nop |
1378 | 1454 | ||
1379 | naitlb_check_alias_20w: | 1455 | naitlb_check_alias_20w: |
1380 | do_alias spc,t0,t1,va,pte,prot,naitlb_fault,20 | 1456 | do_alias spc,t0,t1,va,pte,prot,naitlb_fault |
1381 | 1457 | ||
1382 | iitlbt pte,prot | 1458 | iitlbt pte,prot |
1383 | 1459 | ||
@@ -1431,7 +1507,7 @@ naitlb_miss_11: | |||
1431 | nop | 1507 | nop |
1432 | 1508 | ||
1433 | naitlb_check_alias_11: | 1509 | naitlb_check_alias_11: |
1434 | do_alias spc,t0,t1,va,pte,prot,itlb_fault,11 | 1510 | do_alias spc,t0,t1,va,pte,prot,itlb_fault |
1435 | 1511 | ||
1436 | iitlba pte,(%sr0, va) | 1512 | iitlba pte,(%sr0, va) |
1437 | iitlbp prot,(%sr0, va) | 1513 | iitlbp prot,(%sr0, va) |
@@ -1477,7 +1553,7 @@ naitlb_miss_20: | |||
1477 | nop | 1553 | nop |
1478 | 1554 | ||
1479 | naitlb_check_alias_20: | 1555 | naitlb_check_alias_20: |
1480 | do_alias spc,t0,t1,va,pte,prot,naitlb_fault,20 | 1556 | do_alias spc,t0,t1,va,pte,prot,naitlb_fault |
1481 | 1557 | ||
1482 | iitlbt pte,prot | 1558 | iitlbt pte,prot |
1483 | 1559 | ||
@@ -1688,36 +1764,151 @@ dtlb_fault: | |||
1688 | LDREG PT_GR18(\regs),%r18 | 1764 | LDREG PT_GR18(\regs),%r18 |
1689 | .endm | 1765 | .endm |
1690 | 1766 | ||
1691 | .macro fork_like name | 1767 | ENTRY(sys_fork_wrapper) |
1692 | ENTRY(sys_\name\()_wrapper) | ||
1693 | LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1 | 1768 | LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1 |
1694 | ldo TASK_REGS(%r1),%r1 | 1769 | ldo TASK_REGS(%r1),%r1 |
1695 | reg_save %r1 | 1770 | reg_save %r1 |
1696 | mfctl %cr27, %r28 | 1771 | mfctl %cr27, %r3 |
1697 | b sys_\name | 1772 | STREG %r3, PT_CR27(%r1) |
1698 | STREG %r28, PT_CR27(%r1) | ||
1699 | ENDPROC(sys_\name\()_wrapper) | ||
1700 | .endm | ||
1701 | 1773 | ||
1702 | fork_like clone | 1774 | STREG %r2,-RP_OFFSET(%r30) |
1703 | fork_like fork | 1775 | ldo FRAME_SIZE(%r30),%r30 |
1704 | fork_like vfork | 1776 | #ifdef CONFIG_64BIT |
1777 | ldo -16(%r30),%r29 /* Reference param save area */ | ||
1778 | #endif | ||
1705 | 1779 | ||
1706 | /* Set the return value for the child */ | 1780 | /* These are call-clobbered registers and therefore |
1707 | ENTRY(child_return) | 1781 | also syscall-clobbered (we hope). */ |
1708 | BL schedule_tail, %r2 | 1782 | STREG %r2,PT_GR19(%r1) /* save for child */ |
1709 | nop | 1783 | STREG %r30,PT_GR21(%r1) |
1710 | finish_child_return: | 1784 | |
1711 | LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1 | 1785 | LDREG PT_GR30(%r1),%r25 |
1786 | copy %r1,%r24 | ||
1787 | BL sys_clone,%r2 | ||
1788 | ldi SIGCHLD,%r26 | ||
1789 | |||
1790 | LDREG -RP_OFFSET-FRAME_SIZE(%r30),%r2 | ||
1791 | wrapper_exit: | ||
1792 | ldo -FRAME_SIZE(%r30),%r30 /* get the stackframe */ | ||
1793 | LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 | ||
1712 | ldo TASK_REGS(%r1),%r1 /* get pt regs */ | 1794 | ldo TASK_REGS(%r1),%r1 /* get pt regs */ |
1713 | 1795 | ||
1714 | LDREG PT_CR27(%r1), %r3 | 1796 | LDREG PT_CR27(%r1), %r3 |
1715 | mtctl %r3, %cr27 | 1797 | mtctl %r3, %cr27 |
1716 | reg_restore %r1 | 1798 | reg_restore %r1 |
1717 | b syscall_exit | 1799 | |
1800 | /* strace expects syscall # to be preserved in r20 */ | ||
1801 | ldi __NR_fork,%r20 | ||
1802 | bv %r0(%r2) | ||
1803 | STREG %r20,PT_GR20(%r1) | ||
1804 | ENDPROC(sys_fork_wrapper) | ||
1805 | |||
1806 | /* Set the return value for the child */ | ||
1807 | ENTRY(child_return) | ||
1808 | BL schedule_tail, %r2 | ||
1809 | nop | ||
1810 | |||
1811 | LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE-FRAME_SIZE(%r30), %r1 | ||
1812 | LDREG TASK_PT_GR19(%r1),%r2 | ||
1813 | b wrapper_exit | ||
1718 | copy %r0,%r28 | 1814 | copy %r0,%r28 |
1719 | ENDPROC(child_return) | 1815 | ENDPROC(child_return) |
1720 | 1816 | ||
1817 | |||
1818 | ENTRY(sys_clone_wrapper) | ||
1819 | LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 | ||
1820 | ldo TASK_REGS(%r1),%r1 /* get pt regs */ | ||
1821 | reg_save %r1 | ||
1822 | mfctl %cr27, %r3 | ||
1823 | STREG %r3, PT_CR27(%r1) | ||
1824 | |||
1825 | STREG %r2,-RP_OFFSET(%r30) | ||
1826 | ldo FRAME_SIZE(%r30),%r30 | ||
1827 | #ifdef CONFIG_64BIT | ||
1828 | ldo -16(%r30),%r29 /* Reference param save area */ | ||
1829 | #endif | ||
1830 | |||
1831 | /* WARNING - Clobbers r19 and r21, userspace must save these! */ | ||
1832 | STREG %r2,PT_GR19(%r1) /* save for child */ | ||
1833 | STREG %r30,PT_GR21(%r1) | ||
1834 | BL sys_clone,%r2 | ||
1835 | copy %r1,%r24 | ||
1836 | |||
1837 | b wrapper_exit | ||
1838 | LDREG -RP_OFFSET-FRAME_SIZE(%r30),%r2 | ||
1839 | ENDPROC(sys_clone_wrapper) | ||
1840 | |||
1841 | |||
1842 | ENTRY(sys_vfork_wrapper) | ||
1843 | LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 | ||
1844 | ldo TASK_REGS(%r1),%r1 /* get pt regs */ | ||
1845 | reg_save %r1 | ||
1846 | mfctl %cr27, %r3 | ||
1847 | STREG %r3, PT_CR27(%r1) | ||
1848 | |||
1849 | STREG %r2,-RP_OFFSET(%r30) | ||
1850 | ldo FRAME_SIZE(%r30),%r30 | ||
1851 | #ifdef CONFIG_64BIT | ||
1852 | ldo -16(%r30),%r29 /* Reference param save area */ | ||
1853 | #endif | ||
1854 | |||
1855 | STREG %r2,PT_GR19(%r1) /* save for child */ | ||
1856 | STREG %r30,PT_GR21(%r1) | ||
1857 | |||
1858 | BL sys_vfork,%r2 | ||
1859 | copy %r1,%r26 | ||
1860 | |||
1861 | b wrapper_exit | ||
1862 | LDREG -RP_OFFSET-FRAME_SIZE(%r30),%r2 | ||
1863 | ENDPROC(sys_vfork_wrapper) | ||
1864 | |||
1865 | |||
1866 | .macro execve_wrapper execve | ||
1867 | LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 | ||
1868 | ldo TASK_REGS(%r1),%r1 /* get pt regs */ | ||
1869 | |||
1870 | /* | ||
1871 | * Do we need to save/restore r3-r18 here? | ||
1872 | * I don't think so. why would new thread need old | ||
1873 | * threads registers? | ||
1874 | */ | ||
1875 | |||
1876 | /* %arg0 - %arg3 are already saved for us. */ | ||
1877 | |||
1878 | STREG %r2,-RP_OFFSET(%r30) | ||
1879 | ldo FRAME_SIZE(%r30),%r30 | ||
1880 | #ifdef CONFIG_64BIT | ||
1881 | ldo -16(%r30),%r29 /* Reference param save area */ | ||
1882 | #endif | ||
1883 | BL \execve,%r2 | ||
1884 | copy %r1,%arg0 | ||
1885 | |||
1886 | ldo -FRAME_SIZE(%r30),%r30 | ||
1887 | LDREG -RP_OFFSET(%r30),%r2 | ||
1888 | |||
1889 | /* If exec succeeded we need to load the args */ | ||
1890 | |||
1891 | ldo -1024(%r0),%r1 | ||
1892 | cmpb,>>= %r28,%r1,error_\execve | ||
1893 | copy %r2,%r19 | ||
1894 | |||
1895 | error_\execve: | ||
1896 | bv %r0(%r19) | ||
1897 | nop | ||
1898 | .endm | ||
1899 | |||
1900 | .import sys_execve | ||
1901 | ENTRY(sys_execve_wrapper) | ||
1902 | execve_wrapper sys_execve | ||
1903 | ENDPROC(sys_execve_wrapper) | ||
1904 | |||
1905 | #ifdef CONFIG_64BIT | ||
1906 | .import sys32_execve | ||
1907 | ENTRY(sys32_execve_wrapper) | ||
1908 | execve_wrapper sys32_execve | ||
1909 | ENDPROC(sys32_execve_wrapper) | ||
1910 | #endif | ||
1911 | |||
1721 | ENTRY(sys_rt_sigreturn_wrapper) | 1912 | ENTRY(sys_rt_sigreturn_wrapper) |
1722 | LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r26 | 1913 | LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r26 |
1723 | ldo TASK_REGS(%r26),%r26 /* get pt regs */ | 1914 | ldo TASK_REGS(%r26),%r26 /* get pt regs */ |
@@ -1833,7 +2024,7 @@ syscall_check_resched: | |||
1833 | .import do_signal,code | 2024 | .import do_signal,code |
1834 | syscall_check_sig: | 2025 | syscall_check_sig: |
1835 | LDREG TI_FLAGS-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r19 | 2026 | LDREG TI_FLAGS-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r19 |
1836 | ldi (_TIF_SIGPENDING|_TIF_NOTIFY_RESUME), %r26 | 2027 | ldi (_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK), %r26 |
1837 | and,COND(<>) %r19, %r26, %r0 | 2028 | and,COND(<>) %r19, %r26, %r0 |
1838 | b,n syscall_restore /* skip past if we've nothing to do */ | 2029 | b,n syscall_restore /* skip past if we've nothing to do */ |
1839 | 2030 | ||
diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c index f65fa480c90..4896ed09058 100644 --- a/arch/parisc/kernel/firmware.c +++ b/arch/parisc/kernel/firmware.c | |||
@@ -67,6 +67,7 @@ | |||
67 | #include <asm/page.h> | 67 | #include <asm/page.h> |
68 | #include <asm/pdc.h> | 68 | #include <asm/pdc.h> |
69 | #include <asm/pdcpat.h> | 69 | #include <asm/pdcpat.h> |
70 | #include <asm/system.h> | ||
70 | #include <asm/processor.h> /* for boot_cpu_data */ | 71 | #include <asm/processor.h> /* for boot_cpu_data */ |
71 | 72 | ||
72 | static DEFINE_SPINLOCK(pdc_lock); | 73 | static DEFINE_SPINLOCK(pdc_lock); |
diff --git a/arch/parisc/kernel/hardware.c b/arch/parisc/kernel/hardware.c index f7752f6af29..f48a640b55f 100644 --- a/arch/parisc/kernel/hardware.c +++ b/arch/parisc/kernel/hardware.c | |||
@@ -38,7 +38,7 @@ | |||
38 | * so don't reference this table after starting the init process | 38 | * so don't reference this table after starting the init process |
39 | */ | 39 | */ |
40 | 40 | ||
41 | static struct hp_hardware hp_hardware_list[] = { | 41 | static struct hp_hardware hp_hardware_list[] __devinitdata = { |
42 | {HPHW_NPROC,0x01,0x4,0x0,"Indigo (840, 930)"}, | 42 | {HPHW_NPROC,0x01,0x4,0x0,"Indigo (840, 930)"}, |
43 | {HPHW_NPROC,0x8,0x4,0x01,"Firefox(825,925)"}, | 43 | {HPHW_NPROC,0x8,0x4,0x01,"Firefox(825,925)"}, |
44 | {HPHW_NPROC,0xA,0x4,0x01,"Top Gun (835,834,935,635)"}, | 44 | {HPHW_NPROC,0xA,0x4,0x01,"Top Gun (835,834,935,635)"}, |
@@ -1230,7 +1230,7 @@ static struct hp_cpu_type_mask { | |||
1230 | unsigned short model; | 1230 | unsigned short model; |
1231 | unsigned short mask; | 1231 | unsigned short mask; |
1232 | enum cpu_type cpu; | 1232 | enum cpu_type cpu; |
1233 | } hp_cpu_type_mask_list[] = { | 1233 | } hp_cpu_type_mask_list[] __devinitdata = { |
1234 | 1234 | ||
1235 | { 0x0000, 0x0ff0, pcx }, /* 0x0000 - 0x000f */ | 1235 | { 0x0000, 0x0ff0, pcx }, /* 0x0000 - 0x000f */ |
1236 | { 0x0048, 0x0ff0, pcxl }, /* 0x0040 - 0x004f */ | 1236 | { 0x0048, 0x0ff0, pcxl }, /* 0x0040 - 0x004f */ |
@@ -1327,7 +1327,8 @@ const char * const cpu_name_version[][2] = { | |||
1327 | [mako2] = { "PA8900 (Shortfin)", "2.0" } | 1327 | [mako2] = { "PA8900 (Shortfin)", "2.0" } |
1328 | }; | 1328 | }; |
1329 | 1329 | ||
1330 | const char *parisc_hardware_description(struct parisc_device_id *id) | 1330 | const char * __devinit |
1331 | parisc_hardware_description(struct parisc_device_id *id) | ||
1331 | { | 1332 | { |
1332 | struct hp_hardware *listptr; | 1333 | struct hp_hardware *listptr; |
1333 | 1334 | ||
diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c index 2a625fb063e..5e34ccf39a4 100644 --- a/arch/parisc/kernel/module.c +++ b/arch/parisc/kernel/module.c | |||
@@ -214,6 +214,8 @@ static inline int reassemble_22(int as22) | |||
214 | 214 | ||
215 | void *module_alloc(unsigned long size) | 215 | void *module_alloc(unsigned long size) |
216 | { | 216 | { |
217 | if (size == 0) | ||
218 | return NULL; | ||
217 | /* using RWX means less protection for modules, but it's | 219 | /* using RWX means less protection for modules, but it's |
218 | * easier than trying to map the text, data, init_text and | 220 | * easier than trying to map the text, data, init_text and |
219 | * init_data correctly */ | 221 | * init_data correctly */ |
diff --git a/arch/parisc/kernel/pacache.S b/arch/parisc/kernel/pacache.S index 5d7218ad885..93ff3d90edd 100644 --- a/arch/parisc/kernel/pacache.S +++ b/arch/parisc/kernel/pacache.S | |||
@@ -692,7 +692,7 @@ ENTRY(flush_icache_page_asm) | |||
692 | 692 | ||
693 | /* Purge any old translation */ | 693 | /* Purge any old translation */ |
694 | 694 | ||
695 | pitlb (%sr4,%r28) | 695 | pitlb (%sr0,%r28) |
696 | 696 | ||
697 | ldil L%icache_stride, %r1 | 697 | ldil L%icache_stride, %r1 |
698 | ldw R%icache_stride(%r1), %r1 | 698 | ldw R%icache_stride(%r1), %r1 |
@@ -706,29 +706,27 @@ ENTRY(flush_icache_page_asm) | |||
706 | sub %r25, %r1, %r25 | 706 | sub %r25, %r1, %r25 |
707 | 707 | ||
708 | 708 | ||
709 | /* fic only has the type 26 form on PA1.1, requiring an | 709 | 1: fic,m %r1(%r28) |
710 | * explicit space specification, so use %sr4 */ | 710 | fic,m %r1(%r28) |
711 | 1: fic,m %r1(%sr4,%r28) | 711 | fic,m %r1(%r28) |
712 | fic,m %r1(%sr4,%r28) | 712 | fic,m %r1(%r28) |
713 | fic,m %r1(%sr4,%r28) | 713 | fic,m %r1(%r28) |
714 | fic,m %r1(%sr4,%r28) | 714 | fic,m %r1(%r28) |
715 | fic,m %r1(%sr4,%r28) | 715 | fic,m %r1(%r28) |
716 | fic,m %r1(%sr4,%r28) | 716 | fic,m %r1(%r28) |
717 | fic,m %r1(%sr4,%r28) | 717 | fic,m %r1(%r28) |
718 | fic,m %r1(%sr4,%r28) | 718 | fic,m %r1(%r28) |
719 | fic,m %r1(%sr4,%r28) | 719 | fic,m %r1(%r28) |
720 | fic,m %r1(%sr4,%r28) | 720 | fic,m %r1(%r28) |
721 | fic,m %r1(%sr4,%r28) | 721 | fic,m %r1(%r28) |
722 | fic,m %r1(%sr4,%r28) | 722 | fic,m %r1(%r28) |
723 | fic,m %r1(%sr4,%r28) | 723 | fic,m %r1(%r28) |
724 | fic,m %r1(%sr4,%r28) | ||
725 | fic,m %r1(%sr4,%r28) | ||
726 | cmpb,COND(<<) %r28, %r25,1b | 724 | cmpb,COND(<<) %r28, %r25,1b |
727 | fic,m %r1(%sr4,%r28) | 725 | fic,m %r1(%r28) |
728 | 726 | ||
729 | sync | 727 | sync |
730 | bv %r0(%r2) | 728 | bv %r0(%r2) |
731 | pitlb (%sr4,%r25) | 729 | pitlb (%sr0,%r25) |
732 | .exit | 730 | .exit |
733 | 731 | ||
734 | .procend | 732 | .procend |
diff --git a/arch/parisc/kernel/parisc_ksyms.c b/arch/parisc/kernel/parisc_ksyms.c index ceec85de629..a7bb757a549 100644 --- a/arch/parisc/kernel/parisc_ksyms.c +++ b/arch/parisc/kernel/parisc_ksyms.c | |||
@@ -44,6 +44,7 @@ EXPORT_SYMBOL(__cmpxchg_u64); | |||
44 | #endif | 44 | #endif |
45 | 45 | ||
46 | #include <asm/uaccess.h> | 46 | #include <asm/uaccess.h> |
47 | EXPORT_SYMBOL(lstrncpy_from_user); | ||
47 | EXPORT_SYMBOL(lclear_user); | 48 | EXPORT_SYMBOL(lclear_user); |
48 | EXPORT_SYMBOL(lstrnlen_user); | 49 | EXPORT_SYMBOL(lstrnlen_user); |
49 | 50 | ||
diff --git a/arch/parisc/kernel/pci-dma.c b/arch/parisc/kernel/pci-dma.c index d87d1c476d8..a029f74a3c5 100644 --- a/arch/parisc/kernel/pci-dma.c +++ b/arch/parisc/kernel/pci-dma.c | |||
@@ -2,7 +2,7 @@ | |||
2 | ** PARISC 1.1 Dynamic DMA mapping support. | 2 | ** PARISC 1.1 Dynamic DMA mapping support. |
3 | ** This implementation is for PA-RISC platforms that do not support | 3 | ** This implementation is for PA-RISC platforms that do not support |
4 | ** I/O TLBs (aka DMA address translation hardware). | 4 | ** I/O TLBs (aka DMA address translation hardware). |
5 | ** See Documentation/DMA-API-HOWTO.txt for interface definitions. | 5 | ** See Documentation/PCI/PCI-DMA-mapping.txt for interface definitions. |
6 | ** | 6 | ** |
7 | ** (c) Copyright 1999,2000 Hewlett-Packard Company | 7 | ** (c) Copyright 1999,2000 Hewlett-Packard Company |
8 | ** (c) Copyright 2000 Grant Grundler | 8 | ** (c) Copyright 2000 Grant Grundler |
@@ -26,7 +26,6 @@ | |||
26 | #include <linux/string.h> | 26 | #include <linux/string.h> |
27 | #include <linux/types.h> | 27 | #include <linux/types.h> |
28 | #include <linux/scatterlist.h> | 28 | #include <linux/scatterlist.h> |
29 | #include <linux/export.h> | ||
30 | 29 | ||
31 | #include <asm/cacheflush.h> | 30 | #include <asm/cacheflush.h> |
32 | #include <asm/dma.h> /* for DMA_CHUNK_SIZE */ | 31 | #include <asm/dma.h> /* for DMA_CHUNK_SIZE */ |
diff --git a/arch/parisc/kernel/pci.c b/arch/parisc/kernel/pci.c index 60309051875..9efd9740531 100644 --- a/arch/parisc/kernel/pci.c +++ b/arch/parisc/kernel/pci.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/types.h> | 16 | #include <linux/types.h> |
17 | 17 | ||
18 | #include <asm/io.h> | 18 | #include <asm/io.h> |
19 | #include <asm/system.h> | ||
19 | #include <asm/superio.h> | 20 | #include <asm/superio.h> |
20 | 21 | ||
21 | #define DEBUG_RESOURCES 0 | 22 | #define DEBUG_RESOURCES 0 |
@@ -139,6 +140,11 @@ void pcibios_fixup_bus(struct pci_bus *bus) | |||
139 | } | 140 | } |
140 | 141 | ||
141 | 142 | ||
143 | char *pcibios_setup(char *str) | ||
144 | { | ||
145 | return str; | ||
146 | } | ||
147 | |||
142 | /* | 148 | /* |
143 | * Called by pci_set_master() - a driver interface. | 149 | * Called by pci_set_master() - a driver interface. |
144 | * | 150 | * |
@@ -189,6 +195,58 @@ void __init pcibios_init_bus(struct pci_bus *bus) | |||
189 | pci_write_config_word(dev, PCI_BRIDGE_CONTROL, bridge_ctl); | 195 | pci_write_config_word(dev, PCI_BRIDGE_CONTROL, bridge_ctl); |
190 | } | 196 | } |
191 | 197 | ||
198 | /* called by drivers/pci/setup-bus.c:pci_setup_bridge(). */ | ||
199 | void __devinit pcibios_resource_to_bus(struct pci_dev *dev, | ||
200 | struct pci_bus_region *region, struct resource *res) | ||
201 | { | ||
202 | #ifdef CONFIG_64BIT | ||
203 | struct pci_hba_data *hba = HBA_DATA(dev->bus->bridge->platform_data); | ||
204 | #endif | ||
205 | |||
206 | if (res->flags & IORESOURCE_IO) { | ||
207 | /* | ||
208 | ** I/O space may see busnumbers here. Something | ||
209 | ** in the form of 0xbbxxxx where bb is the bus num | ||
210 | ** and xxxx is the I/O port space address. | ||
211 | ** Remaining address translation are done in the | ||
212 | ** PCI Host adapter specific code - ie dino_out8. | ||
213 | */ | ||
214 | region->start = PCI_PORT_ADDR(res->start); | ||
215 | region->end = PCI_PORT_ADDR(res->end); | ||
216 | } else if (res->flags & IORESOURCE_MEM) { | ||
217 | /* Convert MMIO addr to PCI addr (undo global virtualization) */ | ||
218 | region->start = PCI_BUS_ADDR(hba, res->start); | ||
219 | region->end = PCI_BUS_ADDR(hba, res->end); | ||
220 | } | ||
221 | |||
222 | DBG_RES("pcibios_resource_to_bus(%02x %s [%lx,%lx])\n", | ||
223 | dev->bus->number, res->flags & IORESOURCE_IO ? "IO" : "MEM", | ||
224 | region->start, region->end); | ||
225 | } | ||
226 | |||
227 | void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, | ||
228 | struct pci_bus_region *region) | ||
229 | { | ||
230 | #ifdef CONFIG_64BIT | ||
231 | struct pci_hba_data *hba = HBA_DATA(dev->bus->bridge->platform_data); | ||
232 | #endif | ||
233 | |||
234 | if (res->flags & IORESOURCE_MEM) { | ||
235 | res->start = PCI_HOST_ADDR(hba, region->start); | ||
236 | res->end = PCI_HOST_ADDR(hba, region->end); | ||
237 | } | ||
238 | |||
239 | if (res->flags & IORESOURCE_IO) { | ||
240 | res->start = region->start; | ||
241 | res->end = region->end; | ||
242 | } | ||
243 | } | ||
244 | |||
245 | #ifdef CONFIG_HOTPLUG | ||
246 | EXPORT_SYMBOL(pcibios_resource_to_bus); | ||
247 | EXPORT_SYMBOL(pcibios_bus_to_resource); | ||
248 | #endif | ||
249 | |||
192 | /* | 250 | /* |
193 | * pcibios align resources() is called every time generic PCI code | 251 | * pcibios align resources() is called every time generic PCI code |
194 | * wants to generate a new address. The process of looking for | 252 | * wants to generate a new address. The process of looking for |
diff --git a/arch/parisc/kernel/pdc_cons.c b/arch/parisc/kernel/pdc_cons.c index efc5e7d3053..fc770be465f 100644 --- a/arch/parisc/kernel/pdc_cons.c +++ b/arch/parisc/kernel/pdc_cons.c | |||
@@ -50,7 +50,6 @@ | |||
50 | #include <linux/init.h> | 50 | #include <linux/init.h> |
51 | #include <linux/major.h> | 51 | #include <linux/major.h> |
52 | #include <linux/tty.h> | 52 | #include <linux/tty.h> |
53 | #include <asm/page.h> /* for PAGE0 */ | ||
54 | #include <asm/pdc.h> /* for iodc_call() proto and friends */ | 53 | #include <asm/pdc.h> /* for iodc_call() proto and friends */ |
55 | 54 | ||
56 | static DEFINE_SPINLOCK(pdc_console_lock); | 55 | static DEFINE_SPINLOCK(pdc_console_lock); |
@@ -91,13 +90,11 @@ static int pdc_console_setup(struct console *co, char *options) | |||
91 | 90 | ||
92 | #define PDC_CONS_POLL_DELAY (30 * HZ / 1000) | 91 | #define PDC_CONS_POLL_DELAY (30 * HZ / 1000) |
93 | 92 | ||
94 | static void pdc_console_poll(unsigned long unused); | 93 | static struct timer_list pdc_console_timer; |
95 | static DEFINE_TIMER(pdc_console_timer, pdc_console_poll, 0, 0); | ||
96 | static struct tty_port tty_port; | ||
97 | 94 | ||
98 | static int pdc_console_tty_open(struct tty_struct *tty, struct file *filp) | 95 | static int pdc_console_tty_open(struct tty_struct *tty, struct file *filp) |
99 | { | 96 | { |
100 | tty_port_tty_set(&tty_port, tty); | 97 | |
101 | mod_timer(&pdc_console_timer, jiffies + PDC_CONS_POLL_DELAY); | 98 | mod_timer(&pdc_console_timer, jiffies + PDC_CONS_POLL_DELAY); |
102 | 99 | ||
103 | return 0; | 100 | return 0; |
@@ -105,10 +102,8 @@ static int pdc_console_tty_open(struct tty_struct *tty, struct file *filp) | |||
105 | 102 | ||
106 | static void pdc_console_tty_close(struct tty_struct *tty, struct file *filp) | 103 | static void pdc_console_tty_close(struct tty_struct *tty, struct file *filp) |
107 | { | 104 | { |
108 | if (tty->count == 1) { | 105 | if (!tty->count) |
109 | del_timer_sync(&pdc_console_timer); | 106 | del_timer(&pdc_console_timer); |
110 | tty_port_tty_set(&tty_port, NULL); | ||
111 | } | ||
112 | } | 107 | } |
113 | 108 | ||
114 | static int pdc_console_tty_write(struct tty_struct *tty, const unsigned char *buf, int count) | 109 | static int pdc_console_tty_write(struct tty_struct *tty, const unsigned char *buf, int count) |
@@ -127,6 +122,8 @@ static int pdc_console_tty_chars_in_buffer(struct tty_struct *tty) | |||
127 | return 0; /* no buffer */ | 122 | return 0; /* no buffer */ |
128 | } | 123 | } |
129 | 124 | ||
125 | static struct tty_driver *pdc_console_tty_driver; | ||
126 | |||
130 | static const struct tty_operations pdc_console_tty_ops = { | 127 | static const struct tty_operations pdc_console_tty_ops = { |
131 | .open = pdc_console_tty_open, | 128 | .open = pdc_console_tty_open, |
132 | .close = pdc_console_tty_close, | 129 | .close = pdc_console_tty_close, |
@@ -137,8 +134,10 @@ static const struct tty_operations pdc_console_tty_ops = { | |||
137 | 134 | ||
138 | static void pdc_console_poll(unsigned long unused) | 135 | static void pdc_console_poll(unsigned long unused) |
139 | { | 136 | { |
137 | |||
140 | int data, count = 0; | 138 | int data, count = 0; |
141 | struct tty_struct *tty = tty_port_tty_get(&tty_port); | 139 | |
140 | struct tty_struct *tty = pdc_console_tty_driver->ttys[0]; | ||
142 | 141 | ||
143 | if (!tty) | 142 | if (!tty) |
144 | return; | 143 | return; |
@@ -154,17 +153,15 @@ static void pdc_console_poll(unsigned long unused) | |||
154 | if (count) | 153 | if (count) |
155 | tty_flip_buffer_push(tty); | 154 | tty_flip_buffer_push(tty); |
156 | 155 | ||
157 | tty_kref_put(tty); | 156 | if (tty->count && (pdc_cons.flags & CON_ENABLED)) |
158 | |||
159 | if (pdc_cons.flags & CON_ENABLED) | ||
160 | mod_timer(&pdc_console_timer, jiffies + PDC_CONS_POLL_DELAY); | 157 | mod_timer(&pdc_console_timer, jiffies + PDC_CONS_POLL_DELAY); |
161 | } | 158 | } |
162 | 159 | ||
163 | static struct tty_driver *pdc_console_tty_driver; | ||
164 | |||
165 | static int __init pdc_console_tty_driver_init(void) | 160 | static int __init pdc_console_tty_driver_init(void) |
166 | { | 161 | { |
162 | |||
167 | int err; | 163 | int err; |
164 | struct tty_driver *drv; | ||
168 | 165 | ||
169 | /* Check if the console driver is still registered. | 166 | /* Check if the console driver is still registered. |
170 | * It is unregistered if the pdc console was not selected as the | 167 | * It is unregistered if the pdc console was not selected as the |
@@ -186,31 +183,32 @@ static int __init pdc_console_tty_driver_init(void) | |||
186 | printk(KERN_INFO "The PDC console driver is still registered, removing CON_BOOT flag\n"); | 183 | printk(KERN_INFO "The PDC console driver is still registered, removing CON_BOOT flag\n"); |
187 | pdc_cons.flags &= ~CON_BOOT; | 184 | pdc_cons.flags &= ~CON_BOOT; |
188 | 185 | ||
189 | pdc_console_tty_driver = alloc_tty_driver(1); | 186 | drv = alloc_tty_driver(1); |
190 | 187 | ||
191 | if (!pdc_console_tty_driver) | 188 | if (!drv) |
192 | return -ENOMEM; | 189 | return -ENOMEM; |
193 | 190 | ||
194 | tty_port_init(&tty_port); | 191 | drv->driver_name = "pdc_cons"; |
192 | drv->name = "ttyB"; | ||
193 | drv->major = MUX_MAJOR; | ||
194 | drv->minor_start = 0; | ||
195 | drv->type = TTY_DRIVER_TYPE_SYSTEM; | ||
196 | drv->init_termios = tty_std_termios; | ||
197 | drv->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS; | ||
198 | tty_set_operations(drv, &pdc_console_tty_ops); | ||
195 | 199 | ||
196 | pdc_console_tty_driver->driver_name = "pdc_cons"; | 200 | err = tty_register_driver(drv); |
197 | pdc_console_tty_driver->name = "ttyB"; | ||
198 | pdc_console_tty_driver->major = MUX_MAJOR; | ||
199 | pdc_console_tty_driver->minor_start = 0; | ||
200 | pdc_console_tty_driver->type = TTY_DRIVER_TYPE_SYSTEM; | ||
201 | pdc_console_tty_driver->init_termios = tty_std_termios; | ||
202 | pdc_console_tty_driver->flags = TTY_DRIVER_REAL_RAW | | ||
203 | TTY_DRIVER_RESET_TERMIOS; | ||
204 | tty_set_operations(pdc_console_tty_driver, &pdc_console_tty_ops); | ||
205 | tty_port_link_device(&tty_port, pdc_console_tty_driver, 0); | ||
206 | |||
207 | err = tty_register_driver(pdc_console_tty_driver); | ||
208 | if (err) { | 201 | if (err) { |
209 | printk(KERN_ERR "Unable to register the PDC console TTY driver\n"); | 202 | printk(KERN_ERR "Unable to register the PDC console TTY driver\n"); |
210 | tty_port_destroy(&tty_port); | ||
211 | return err; | 203 | return err; |
212 | } | 204 | } |
213 | 205 | ||
206 | pdc_console_tty_driver = drv; | ||
207 | |||
208 | /* No need to initialize the pdc_console_timer if tty isn't allocated */ | ||
209 | init_timer(&pdc_console_timer); | ||
210 | pdc_console_timer.function = pdc_console_poll; | ||
211 | |||
214 | return 0; | 212 | return 0; |
215 | } | 213 | } |
216 | 214 | ||
diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c index d13507246c5..4b4b9181a1a 100644 --- a/arch/parisc/kernel/process.c +++ b/arch/parisc/kernel/process.c | |||
@@ -48,11 +48,9 @@ | |||
48 | #include <linux/unistd.h> | 48 | #include <linux/unistd.h> |
49 | #include <linux/kallsyms.h> | 49 | #include <linux/kallsyms.h> |
50 | #include <linux/uaccess.h> | 50 | #include <linux/uaccess.h> |
51 | #include <linux/rcupdate.h> | ||
52 | 51 | ||
53 | #include <asm/io.h> | 52 | #include <asm/io.h> |
54 | #include <asm/asm-offsets.h> | 53 | #include <asm/asm-offsets.h> |
55 | #include <asm/assembly.h> | ||
56 | #include <asm/pdc.h> | 54 | #include <asm/pdc.h> |
57 | #include <asm/pdc_chassis.h> | 55 | #include <asm/pdc_chassis.h> |
58 | #include <asm/pgalloc.h> | 56 | #include <asm/pgalloc.h> |
@@ -71,11 +69,11 @@ void cpu_idle(void) | |||
71 | 69 | ||
72 | /* endless idle loop with no priority at all */ | 70 | /* endless idle loop with no priority at all */ |
73 | while (1) { | 71 | while (1) { |
74 | rcu_idle_enter(); | ||
75 | while (!need_resched()) | 72 | while (!need_resched()) |
76 | barrier(); | 73 | barrier(); |
77 | rcu_idle_exit(); | 74 | preempt_enable_no_resched(); |
78 | schedule_preempt_disabled(); | 75 | schedule(); |
76 | preempt_disable(); | ||
79 | check_pgt_cache(); | 77 | check_pgt_cache(); |
80 | } | 78 | } |
81 | } | 79 | } |
@@ -166,6 +164,23 @@ void (*pm_power_off)(void) = machine_power_off; | |||
166 | EXPORT_SYMBOL(pm_power_off); | 164 | EXPORT_SYMBOL(pm_power_off); |
167 | 165 | ||
168 | /* | 166 | /* |
167 | * Create a kernel thread | ||
168 | */ | ||
169 | |||
170 | extern pid_t __kernel_thread(int (*fn)(void *), void *arg, unsigned long flags); | ||
171 | pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) | ||
172 | { | ||
173 | |||
174 | /* | ||
175 | * FIXME: Once we are sure we don't need any debug here, | ||
176 | * kernel_thread can become a #define. | ||
177 | */ | ||
178 | |||
179 | return __kernel_thread(fn, arg, flags); | ||
180 | } | ||
181 | EXPORT_SYMBOL(kernel_thread); | ||
182 | |||
183 | /* | ||
169 | * Free current thread data structures etc.. | 184 | * Free current thread data structures etc.. |
170 | */ | 185 | */ |
171 | void exit_thread(void) | 186 | void exit_thread(void) |
@@ -177,6 +192,7 @@ void flush_thread(void) | |||
177 | /* Only needs to handle fpu stuff or perf monitors. | 192 | /* Only needs to handle fpu stuff or perf monitors. |
178 | ** REVISIT: several arches implement a "lazy fpu state". | 193 | ** REVISIT: several arches implement a "lazy fpu state". |
179 | */ | 194 | */ |
195 | set_fs(USER_DS); | ||
180 | } | 196 | } |
181 | 197 | ||
182 | void release_thread(struct task_struct *dead_task) | 198 | void release_thread(struct task_struct *dead_task) |
@@ -202,11 +218,48 @@ int dump_task_fpu (struct task_struct *tsk, elf_fpregset_t *r) | |||
202 | return 1; | 218 | return 1; |
203 | } | 219 | } |
204 | 220 | ||
221 | /* Note that "fork()" is implemented in terms of clone, with | ||
222 | parameters (SIGCHLD, regs->gr[30], regs). */ | ||
223 | int | ||
224 | sys_clone(unsigned long clone_flags, unsigned long usp, | ||
225 | struct pt_regs *regs) | ||
226 | { | ||
227 | /* Arugments from userspace are: | ||
228 | r26 = Clone flags. | ||
229 | r25 = Child stack. | ||
230 | r24 = parent_tidptr. | ||
231 | r23 = Is the TLS storage descriptor | ||
232 | r22 = child_tidptr | ||
233 | |||
234 | However, these last 3 args are only examined | ||
235 | if the proper flags are set. */ | ||
236 | int __user *parent_tidptr = (int __user *)regs->gr[24]; | ||
237 | int __user *child_tidptr = (int __user *)regs->gr[22]; | ||
238 | |||
239 | /* usp must be word aligned. This also prevents users from | ||
240 | * passing in the value 1 (which is the signal for a special | ||
241 | * return for a kernel thread) */ | ||
242 | usp = ALIGN(usp, 4); | ||
243 | |||
244 | /* A zero value for usp means use the current stack */ | ||
245 | if (usp == 0) | ||
246 | usp = regs->gr[30]; | ||
247 | |||
248 | return do_fork(clone_flags, usp, regs, 0, parent_tidptr, child_tidptr); | ||
249 | } | ||
250 | |||
251 | int | ||
252 | sys_vfork(struct pt_regs *regs) | ||
253 | { | ||
254 | return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->gr[30], regs, 0, NULL, NULL); | ||
255 | } | ||
256 | |||
205 | int | 257 | int |
206 | copy_thread(unsigned long clone_flags, unsigned long usp, | 258 | copy_thread(unsigned long clone_flags, unsigned long usp, |
207 | unsigned long arg, struct task_struct *p) | 259 | unsigned long unused, /* in ia64 this is "user_stack_size" */ |
260 | struct task_struct * p, struct pt_regs * pregs) | ||
208 | { | 261 | { |
209 | struct pt_regs *cregs = &(p->thread.regs); | 262 | struct pt_regs * cregs = &(p->thread.regs); |
210 | void *stack = task_stack_page(p); | 263 | void *stack = task_stack_page(p); |
211 | 264 | ||
212 | /* We have to use void * instead of a function pointer, because | 265 | /* We have to use void * instead of a function pointer, because |
@@ -217,40 +270,49 @@ copy_thread(unsigned long clone_flags, unsigned long usp, | |||
217 | #ifdef CONFIG_HPUX | 270 | #ifdef CONFIG_HPUX |
218 | extern void * const hpux_child_return; | 271 | extern void * const hpux_child_return; |
219 | #endif | 272 | #endif |
220 | if (unlikely(p->flags & PF_KTHREAD)) { | ||
221 | memset(cregs, 0, sizeof(struct pt_regs)); | ||
222 | if (!usp) /* idle thread */ | ||
223 | return 0; | ||
224 | 273 | ||
274 | *cregs = *pregs; | ||
275 | |||
276 | /* Set the return value for the child. Note that this is not | ||
277 | actually restored by the syscall exit path, but we put it | ||
278 | here for consistency in case of signals. */ | ||
279 | cregs->gr[28] = 0; /* child */ | ||
280 | |||
281 | /* | ||
282 | * We need to differentiate between a user fork and a | ||
283 | * kernel fork. We can't use user_mode, because the | ||
284 | * the syscall path doesn't save iaoq. Right now | ||
285 | * We rely on the fact that kernel_thread passes | ||
286 | * in zero for usp. | ||
287 | */ | ||
288 | if (usp == 1) { | ||
225 | /* kernel thread */ | 289 | /* kernel thread */ |
290 | cregs->ksp = (unsigned long)stack + THREAD_SZ_ALGN; | ||
226 | /* Must exit via ret_from_kernel_thread in order | 291 | /* Must exit via ret_from_kernel_thread in order |
227 | * to call schedule_tail() | 292 | * to call schedule_tail() |
228 | */ | 293 | */ |
229 | cregs->ksp = (unsigned long)stack + THREAD_SZ_ALGN + FRAME_SIZE; | ||
230 | cregs->kpc = (unsigned long) &ret_from_kernel_thread; | 294 | cregs->kpc = (unsigned long) &ret_from_kernel_thread; |
231 | /* | 295 | /* |
232 | * Copy function and argument to be called from | 296 | * Copy function and argument to be called from |
233 | * ret_from_kernel_thread. | 297 | * ret_from_kernel_thread. |
234 | */ | 298 | */ |
235 | #ifdef CONFIG_64BIT | 299 | #ifdef CONFIG_64BIT |
236 | cregs->gr[27] = ((unsigned long *)usp)[3]; | 300 | cregs->gr[27] = pregs->gr[27]; |
237 | cregs->gr[26] = ((unsigned long *)usp)[2]; | ||
238 | #else | ||
239 | cregs->gr[26] = usp; | ||
240 | #endif | 301 | #endif |
241 | cregs->gr[25] = arg; | 302 | cregs->gr[26] = pregs->gr[26]; |
303 | cregs->gr[25] = pregs->gr[25]; | ||
242 | } else { | 304 | } else { |
243 | /* user thread */ | 305 | /* user thread */ |
244 | /* usp must be word aligned. This also prevents users from | 306 | /* |
245 | * passing in the value 1 (which is the signal for a special | 307 | * Note that the fork wrappers are responsible |
246 | * return for a kernel thread) */ | 308 | * for setting gr[21]. |
247 | if (usp) { | 309 | */ |
248 | usp = ALIGN(usp, 4); | 310 | |
249 | if (likely(usp)) | 311 | /* Use same stack depth as parent */ |
250 | cregs->gr[30] = usp; | 312 | cregs->ksp = (unsigned long)stack |
251 | } | 313 | + (pregs->gr[21] & (THREAD_SIZE - 1)); |
252 | cregs->ksp = (unsigned long)stack + THREAD_SZ_ALGN + FRAME_SIZE; | 314 | cregs->gr[30] = usp; |
253 | if (personality(p->personality) == PER_HPUX) { | 315 | if (p->personality == PER_HPUX) { |
254 | #ifdef CONFIG_HPUX | 316 | #ifdef CONFIG_HPUX |
255 | cregs->kpc = (unsigned long) &hpux_child_return; | 317 | cregs->kpc = (unsigned long) &hpux_child_return; |
256 | #else | 318 | #else |
@@ -261,7 +323,8 @@ copy_thread(unsigned long clone_flags, unsigned long usp, | |||
261 | } | 323 | } |
262 | /* Setup thread TLS area from the 4th parameter in clone */ | 324 | /* Setup thread TLS area from the 4th parameter in clone */ |
263 | if (clone_flags & CLONE_SETTLS) | 325 | if (clone_flags & CLONE_SETTLS) |
264 | cregs->cr27 = cregs->gr[23]; | 326 | cregs->cr27 = pregs->gr[23]; |
327 | |||
265 | } | 328 | } |
266 | 329 | ||
267 | return 0; | 330 | return 0; |
@@ -272,6 +335,39 @@ unsigned long thread_saved_pc(struct task_struct *t) | |||
272 | return t->thread.regs.kpc; | 335 | return t->thread.regs.kpc; |
273 | } | 336 | } |
274 | 337 | ||
338 | /* | ||
339 | * sys_execve() executes a new program. | ||
340 | */ | ||
341 | |||
342 | asmlinkage int sys_execve(struct pt_regs *regs) | ||
343 | { | ||
344 | int error; | ||
345 | char *filename; | ||
346 | |||
347 | filename = getname((const char __user *) regs->gr[26]); | ||
348 | error = PTR_ERR(filename); | ||
349 | if (IS_ERR(filename)) | ||
350 | goto out; | ||
351 | error = do_execve(filename, | ||
352 | (const char __user *const __user *) regs->gr[25], | ||
353 | (const char __user *const __user *) regs->gr[24], | ||
354 | regs); | ||
355 | putname(filename); | ||
356 | out: | ||
357 | |||
358 | return error; | ||
359 | } | ||
360 | |||
361 | extern int __execve(const char *filename, | ||
362 | const char *const argv[], | ||
363 | const char *const envp[], struct task_struct *task); | ||
364 | int kernel_execve(const char *filename, | ||
365 | const char *const argv[], | ||
366 | const char *const envp[]) | ||
367 | { | ||
368 | return __execve(filename, argv, envp, current); | ||
369 | } | ||
370 | |||
275 | unsigned long | 371 | unsigned long |
276 | get_wchan(struct task_struct *p) | 372 | get_wchan(struct task_struct *p) |
277 | { | 373 | { |
diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c index 857c2f54547..2905b1f52d3 100644 --- a/arch/parisc/kernel/ptrace.c +++ b/arch/parisc/kernel/ptrace.c | |||
@@ -22,6 +22,7 @@ | |||
22 | 22 | ||
23 | #include <asm/uaccess.h> | 23 | #include <asm/uaccess.h> |
24 | #include <asm/pgtable.h> | 24 | #include <asm/pgtable.h> |
25 | #include <asm/system.h> | ||
25 | #include <asm/processor.h> | 26 | #include <asm/processor.h> |
26 | #include <asm/asm-offsets.h> | 27 | #include <asm/asm-offsets.h> |
27 | 28 | ||
diff --git a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c index a3328c2616b..cb71f3dac99 100644 --- a/arch/parisc/kernel/setup.c +++ b/arch/parisc/kernel/setup.c | |||
@@ -35,7 +35,6 @@ | |||
35 | #include <linux/pci.h> | 35 | #include <linux/pci.h> |
36 | #undef PCI_DEBUG | 36 | #undef PCI_DEBUG |
37 | #include <linux/proc_fs.h> | 37 | #include <linux/proc_fs.h> |
38 | #include <linux/export.h> | ||
39 | 38 | ||
40 | #include <asm/processor.h> | 39 | #include <asm/processor.h> |
41 | #include <asm/pdc.h> | 40 | #include <asm/pdc.h> |
diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c index 53799695599..12c1ed33dc1 100644 --- a/arch/parisc/kernel/signal.c +++ b/arch/parisc/kernel/signal.c | |||
@@ -48,6 +48,9 @@ | |||
48 | #define DBG(LEVEL, ...) | 48 | #define DBG(LEVEL, ...) |
49 | #endif | 49 | #endif |
50 | 50 | ||
51 | |||
52 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) | ||
53 | |||
51 | /* gcc will complain if a pointer is cast to an integer of different | 54 | /* gcc will complain if a pointer is cast to an integer of different |
52 | * size. If you really need to do this (and we do for an ELF32 user | 55 | * size. If you really need to do this (and we do for an ELF32 user |
53 | * application in an ELF64 kernel) then you have to do a cast to an | 56 | * application in an ELF64 kernel) then you have to do a cast to an |
@@ -106,15 +109,12 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall) | |||
106 | sigframe_size = PARISC_RT_SIGFRAME_SIZE32; | 109 | sigframe_size = PARISC_RT_SIGFRAME_SIZE32; |
107 | #endif | 110 | #endif |
108 | 111 | ||
109 | current_thread_info()->restart_block.fn = do_no_restart_syscall; | ||
110 | 112 | ||
111 | /* Unwind the user stack to get the rt_sigframe structure. */ | 113 | /* Unwind the user stack to get the rt_sigframe structure. */ |
112 | frame = (struct rt_sigframe __user *) | 114 | frame = (struct rt_sigframe __user *) |
113 | (usp - sigframe_size); | 115 | (usp - sigframe_size); |
114 | DBG(2,"sys_rt_sigreturn: frame is %p\n", frame); | 116 | DBG(2,"sys_rt_sigreturn: frame is %p\n", frame); |
115 | 117 | ||
116 | regs->orig_r28 = 1; /* no restarts for sigreturn */ | ||
117 | |||
118 | #ifdef CONFIG_64BIT | 118 | #ifdef CONFIG_64BIT |
119 | compat_frame = (struct compat_rt_sigframe __user *)frame; | 119 | compat_frame = (struct compat_rt_sigframe __user *)frame; |
120 | 120 | ||
@@ -130,7 +130,11 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall) | |||
130 | goto give_sigsegv; | 130 | goto give_sigsegv; |
131 | } | 131 | } |
132 | 132 | ||
133 | set_current_blocked(&set); | 133 | sigdelsetmask(&set, ~_BLOCKABLE); |
134 | spin_lock_irq(¤t->sighand->siglock); | ||
135 | current->blocked = set; | ||
136 | recalc_sigpending(); | ||
137 | spin_unlock_irq(¤t->sighand->siglock); | ||
134 | 138 | ||
135 | /* Good thing we saved the old gr[30], eh? */ | 139 | /* Good thing we saved the old gr[30], eh? */ |
136 | #ifdef CONFIG_64BIT | 140 | #ifdef CONFIG_64BIT |
@@ -439,35 +443,39 @@ give_sigsegv: | |||
439 | * OK, we're invoking a handler. | 443 | * OK, we're invoking a handler. |
440 | */ | 444 | */ |
441 | 445 | ||
442 | static void | 446 | static long |
443 | handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, | 447 | handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, |
444 | struct pt_regs *regs, int in_syscall) | 448 | sigset_t *oldset, struct pt_regs *regs, int in_syscall) |
445 | { | 449 | { |
446 | sigset_t *oldset = sigmask_to_save(); | ||
447 | DBG(1,"handle_signal: sig=%ld, ka=%p, info=%p, oldset=%p, regs=%p\n", | 450 | DBG(1,"handle_signal: sig=%ld, ka=%p, info=%p, oldset=%p, regs=%p\n", |
448 | sig, ka, info, oldset, regs); | 451 | sig, ka, info, oldset, regs); |
449 | 452 | ||
450 | /* Set up the stack frame */ | 453 | /* Set up the stack frame */ |
451 | if (!setup_rt_frame(sig, ka, info, oldset, regs, in_syscall)) | 454 | if (!setup_rt_frame(sig, ka, info, oldset, regs, in_syscall)) |
452 | return; | 455 | return 0; |
456 | |||
457 | spin_lock_irq(¤t->sighand->siglock); | ||
458 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | ||
459 | if (!(ka->sa.sa_flags & SA_NODEFER)) | ||
460 | sigaddset(¤t->blocked,sig); | ||
461 | recalc_sigpending(); | ||
462 | spin_unlock_irq(¤t->sighand->siglock); | ||
453 | 463 | ||
454 | signal_delivered(sig, info, ka, regs, | 464 | tracehook_signal_handler(sig, info, ka, regs, |
455 | test_thread_flag(TIF_SINGLESTEP) || | 465 | test_thread_flag(TIF_SINGLESTEP) || |
456 | test_thread_flag(TIF_BLOCKSTEP)); | 466 | test_thread_flag(TIF_BLOCKSTEP)); |
457 | 467 | ||
458 | DBG(1,KERN_DEBUG "do_signal: Exit (success), regs->gr[28] = %ld\n", | 468 | return 1; |
459 | regs->gr[28]); | ||
460 | } | 469 | } |
461 | 470 | ||
462 | static inline void | 471 | static inline void |
463 | syscall_restart(struct pt_regs *regs, struct k_sigaction *ka) | 472 | syscall_restart(struct pt_regs *regs, struct k_sigaction *ka) |
464 | { | 473 | { |
465 | if (regs->orig_r28) | ||
466 | return; | ||
467 | regs->orig_r28 = 1; /* no more restarts */ | ||
468 | /* Check the return code */ | 474 | /* Check the return code */ |
469 | switch (regs->gr[28]) { | 475 | switch (regs->gr[28]) { |
470 | case -ERESTART_RESTARTBLOCK: | 476 | case -ERESTART_RESTARTBLOCK: |
477 | current_thread_info()->restart_block.fn = | ||
478 | do_no_restart_syscall; | ||
471 | case -ERESTARTNOHAND: | 479 | case -ERESTARTNOHAND: |
472 | DBG(1,"ERESTARTNOHAND: returning -EINTR\n"); | 480 | DBG(1,"ERESTARTNOHAND: returning -EINTR\n"); |
473 | regs->gr[28] = -EINTR; | 481 | regs->gr[28] = -EINTR; |
@@ -485,6 +493,8 @@ syscall_restart(struct pt_regs *regs, struct k_sigaction *ka) | |||
485 | * we have to do is fiddle the return pointer. | 493 | * we have to do is fiddle the return pointer. |
486 | */ | 494 | */ |
487 | regs->gr[31] -= 8; /* delayed branching */ | 495 | regs->gr[31] -= 8; /* delayed branching */ |
496 | /* Preserve original r28. */ | ||
497 | regs->gr[28] = regs->orig_r28; | ||
488 | break; | 498 | break; |
489 | } | 499 | } |
490 | } | 500 | } |
@@ -492,9 +502,6 @@ syscall_restart(struct pt_regs *regs, struct k_sigaction *ka) | |||
492 | static inline void | 502 | static inline void |
493 | insert_restart_trampoline(struct pt_regs *regs) | 503 | insert_restart_trampoline(struct pt_regs *regs) |
494 | { | 504 | { |
495 | if (regs->orig_r28) | ||
496 | return; | ||
497 | regs->orig_r28 = 1; /* no more restarts */ | ||
498 | switch(regs->gr[28]) { | 505 | switch(regs->gr[28]) { |
499 | case -ERESTART_RESTARTBLOCK: { | 506 | case -ERESTART_RESTARTBLOCK: { |
500 | /* Restart the system call - no handlers present */ | 507 | /* Restart the system call - no handlers present */ |
@@ -529,6 +536,9 @@ insert_restart_trampoline(struct pt_regs *regs) | |||
529 | flush_user_icache_range(regs->gr[30], regs->gr[30] + 4); | 536 | flush_user_icache_range(regs->gr[30], regs->gr[30] + 4); |
530 | 537 | ||
531 | regs->gr[31] = regs->gr[30] + 8; | 538 | regs->gr[31] = regs->gr[30] + 8; |
539 | /* Preserve original r28. */ | ||
540 | regs->gr[28] = regs->orig_r28; | ||
541 | |||
532 | return; | 542 | return; |
533 | } | 543 | } |
534 | case -ERESTARTNOHAND: | 544 | case -ERESTARTNOHAND: |
@@ -540,6 +550,9 @@ insert_restart_trampoline(struct pt_regs *regs) | |||
540 | * slot of the branch external instruction. | 550 | * slot of the branch external instruction. |
541 | */ | 551 | */ |
542 | regs->gr[31] -= 8; | 552 | regs->gr[31] -= 8; |
553 | /* Preserve original r28. */ | ||
554 | regs->gr[28] = regs->orig_r28; | ||
555 | |||
543 | return; | 556 | return; |
544 | } | 557 | } |
545 | default: | 558 | default: |
@@ -564,21 +577,51 @@ do_signal(struct pt_regs *regs, long in_syscall) | |||
564 | siginfo_t info; | 577 | siginfo_t info; |
565 | struct k_sigaction ka; | 578 | struct k_sigaction ka; |
566 | int signr; | 579 | int signr; |
580 | sigset_t *oldset; | ||
581 | |||
582 | DBG(1,"\ndo_signal: oldset=0x%p, regs=0x%p, sr7 %#lx, in_syscall=%d\n", | ||
583 | oldset, regs, regs->sr[7], in_syscall); | ||
584 | |||
585 | /* Everyone else checks to see if they are in kernel mode at | ||
586 | this point and exits if that's the case. I'm not sure why | ||
587 | we would be called in that case, but for some reason we | ||
588 | are. */ | ||
567 | 589 | ||
568 | DBG(1,"\ndo_signal: regs=0x%p, sr7 %#lx, in_syscall=%d\n", | 590 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) |
569 | regs, regs->sr[7], in_syscall); | 591 | oldset = ¤t->saved_sigmask; |
592 | else | ||
593 | oldset = ¤t->blocked; | ||
570 | 594 | ||
571 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); | 595 | DBG(1,"do_signal: oldset %08lx / %08lx\n", |
572 | DBG(3,"do_signal: signr = %d, regs->gr[28] = %ld\n", signr, regs->gr[28]); | 596 | oldset->sig[0], oldset->sig[1]); |
597 | |||
598 | |||
599 | /* May need to force signal if handle_signal failed to deliver */ | ||
600 | while (1) { | ||
601 | |||
602 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); | ||
603 | DBG(3,"do_signal: signr = %d, regs->gr[28] = %ld\n", signr, regs->gr[28]); | ||
573 | 604 | ||
574 | if (signr > 0) { | 605 | if (signr <= 0) |
606 | break; | ||
607 | |||
575 | /* Restart a system call if necessary. */ | 608 | /* Restart a system call if necessary. */ |
576 | if (in_syscall) | 609 | if (in_syscall) |
577 | syscall_restart(regs, &ka); | 610 | syscall_restart(regs, &ka); |
578 | 611 | ||
579 | handle_signal(signr, &info, &ka, regs, in_syscall); | 612 | /* Whee! Actually deliver the signal. If the |
580 | return; | 613 | delivery failed, we need to continue to iterate in |
614 | this loop so we can deliver the SIGSEGV... */ | ||
615 | if (handle_signal(signr, &info, &ka, oldset, | ||
616 | regs, in_syscall)) { | ||
617 | DBG(1,KERN_DEBUG "do_signal: Exit (success), regs->gr[28] = %ld\n", | ||
618 | regs->gr[28]); | ||
619 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) | ||
620 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
621 | return; | ||
622 | } | ||
581 | } | 623 | } |
624 | /* end of while(1) looping forever if we can't force a signal */ | ||
582 | 625 | ||
583 | /* Did we come from a system call? */ | 626 | /* Did we come from a system call? */ |
584 | if (in_syscall) | 627 | if (in_syscall) |
@@ -587,16 +630,24 @@ do_signal(struct pt_regs *regs, long in_syscall) | |||
587 | DBG(1,"do_signal: Exit (not delivered), regs->gr[28] = %ld\n", | 630 | DBG(1,"do_signal: Exit (not delivered), regs->gr[28] = %ld\n", |
588 | regs->gr[28]); | 631 | regs->gr[28]); |
589 | 632 | ||
590 | restore_saved_sigmask(); | 633 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) { |
634 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
635 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); | ||
636 | } | ||
637 | |||
638 | return; | ||
591 | } | 639 | } |
592 | 640 | ||
593 | void do_notify_resume(struct pt_regs *regs, long in_syscall) | 641 | void do_notify_resume(struct pt_regs *regs, long in_syscall) |
594 | { | 642 | { |
595 | if (test_thread_flag(TIF_SIGPENDING)) | 643 | if (test_thread_flag(TIF_SIGPENDING) || |
644 | test_thread_flag(TIF_RESTORE_SIGMASK)) | ||
596 | do_signal(regs, in_syscall); | 645 | do_signal(regs, in_syscall); |
597 | 646 | ||
598 | if (test_thread_flag(TIF_NOTIFY_RESUME)) { | 647 | if (test_thread_flag(TIF_NOTIFY_RESUME)) { |
599 | clear_thread_flag(TIF_NOTIFY_RESUME); | 648 | clear_thread_flag(TIF_NOTIFY_RESUME); |
600 | tracehook_notify_resume(regs); | 649 | tracehook_notify_resume(regs); |
650 | if (current->replacement_session_keyring) | ||
651 | key_replace_session_keyring(); | ||
601 | } | 652 | } |
602 | } | 653 | } |
diff --git a/arch/parisc/kernel/signal32.c b/arch/parisc/kernel/signal32.c index 5dede04f2f3..e1413243076 100644 --- a/arch/parisc/kernel/signal32.c +++ b/arch/parisc/kernel/signal32.c | |||
@@ -47,6 +47,8 @@ | |||
47 | #define DBG(LEVEL, ...) | 47 | #define DBG(LEVEL, ...) |
48 | #endif | 48 | #endif |
49 | 49 | ||
50 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) | ||
51 | |||
50 | inline void | 52 | inline void |
51 | sigset_32to64(sigset_t *s64, compat_sigset_t *s32) | 53 | sigset_32to64(sigset_t *s64, compat_sigset_t *s32) |
52 | { | 54 | { |
@@ -65,8 +67,7 @@ put_sigset32(compat_sigset_t __user *up, sigset_t *set, size_t sz) | |||
65 | { | 67 | { |
66 | compat_sigset_t s; | 68 | compat_sigset_t s; |
67 | 69 | ||
68 | if (sz != sizeof *set) | 70 | if (sz != sizeof *set) panic("put_sigset32()"); |
69 | return -EINVAL; | ||
70 | sigset_64to32(&s, set); | 71 | sigset_64to32(&s, set); |
71 | 72 | ||
72 | return copy_to_user(up, &s, sizeof s); | 73 | return copy_to_user(up, &s, sizeof s); |
@@ -78,8 +79,7 @@ get_sigset32(compat_sigset_t __user *up, sigset_t *set, size_t sz) | |||
78 | compat_sigset_t s; | 79 | compat_sigset_t s; |
79 | int r; | 80 | int r; |
80 | 81 | ||
81 | if (sz != sizeof *set) | 82 | if (sz != sizeof *set) panic("put_sigset32()"); |
82 | return -EINVAL; | ||
83 | 83 | ||
84 | if ((r = copy_from_user(&s, up, sz)) == 0) { | 84 | if ((r = copy_from_user(&s, up, sz)) == 0) { |
85 | sigset_32to64(set, &s); | 85 | sigset_32to64(set, &s); |
diff --git a/arch/parisc/kernel/signal32.h b/arch/parisc/kernel/signal32.h index 08a88b5349a..c7800846422 100644 --- a/arch/parisc/kernel/signal32.h +++ b/arch/parisc/kernel/signal32.h | |||
@@ -55,6 +55,58 @@ struct k_sigaction32 { | |||
55 | struct compat_sigaction sa; | 55 | struct compat_sigaction sa; |
56 | }; | 56 | }; |
57 | 57 | ||
58 | typedef struct compat_siginfo { | ||
59 | int si_signo; | ||
60 | int si_errno; | ||
61 | int si_code; | ||
62 | |||
63 | union { | ||
64 | int _pad[((128/sizeof(int)) - 3)]; | ||
65 | |||
66 | /* kill() */ | ||
67 | struct { | ||
68 | unsigned int _pid; /* sender's pid */ | ||
69 | unsigned int _uid; /* sender's uid */ | ||
70 | } _kill; | ||
71 | |||
72 | /* POSIX.1b timers */ | ||
73 | struct { | ||
74 | compat_timer_t _tid; /* timer id */ | ||
75 | int _overrun; /* overrun count */ | ||
76 | char _pad[sizeof(unsigned int) - sizeof(int)]; | ||
77 | compat_sigval_t _sigval; /* same as below */ | ||
78 | int _sys_private; /* not to be passed to user */ | ||
79 | } _timer; | ||
80 | |||
81 | /* POSIX.1b signals */ | ||
82 | struct { | ||
83 | unsigned int _pid; /* sender's pid */ | ||
84 | unsigned int _uid; /* sender's uid */ | ||
85 | compat_sigval_t _sigval; | ||
86 | } _rt; | ||
87 | |||
88 | /* SIGCHLD */ | ||
89 | struct { | ||
90 | unsigned int _pid; /* which child */ | ||
91 | unsigned int _uid; /* sender's uid */ | ||
92 | int _status; /* exit code */ | ||
93 | compat_clock_t _utime; | ||
94 | compat_clock_t _stime; | ||
95 | } _sigchld; | ||
96 | |||
97 | /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ | ||
98 | struct { | ||
99 | unsigned int _addr; /* faulting insn/memory ref. */ | ||
100 | } _sigfault; | ||
101 | |||
102 | /* SIGPOLL */ | ||
103 | struct { | ||
104 | int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ | ||
105 | int _fd; | ||
106 | } _sigpoll; | ||
107 | } _sifields; | ||
108 | } compat_siginfo_t; | ||
109 | |||
58 | int copy_siginfo_to_user32 (compat_siginfo_t __user *to, siginfo_t *from); | 110 | int copy_siginfo_to_user32 (compat_siginfo_t __user *to, siginfo_t *from); |
59 | int copy_siginfo_from_user32 (siginfo_t *to, compat_siginfo_t __user *from); | 111 | int copy_siginfo_from_user32 (siginfo_t *to, compat_siginfo_t __user *from); |
60 | 112 | ||
diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c index 6266730efd6..32d588488f0 100644 --- a/arch/parisc/kernel/smp.c +++ b/arch/parisc/kernel/smp.c | |||
@@ -31,8 +31,8 @@ | |||
31 | #include <linux/delay.h> | 31 | #include <linux/delay.h> |
32 | #include <linux/bitops.h> | 32 | #include <linux/bitops.h> |
33 | #include <linux/ftrace.h> | 33 | #include <linux/ftrace.h> |
34 | #include <linux/cpu.h> | ||
35 | 34 | ||
35 | #include <asm/system.h> | ||
36 | #include <linux/atomic.h> | 36 | #include <linux/atomic.h> |
37 | #include <asm/current.h> | 37 | #include <asm/current.h> |
38 | #include <asm/delay.h> | 38 | #include <asm/delay.h> |
@@ -291,15 +291,13 @@ smp_cpu_init(int cpunum) | |||
291 | mb(); | 291 | mb(); |
292 | 292 | ||
293 | /* Well, support 2.4 linux scheme as well. */ | 293 | /* Well, support 2.4 linux scheme as well. */ |
294 | if (cpu_online(cpunum)) { | 294 | if (cpu_isset(cpunum, cpu_online_map)) |
295 | { | ||
295 | extern void machine_halt(void); /* arch/parisc.../process.c */ | 296 | extern void machine_halt(void); /* arch/parisc.../process.c */ |
296 | 297 | ||
297 | printk(KERN_CRIT "CPU#%d already initialized!\n", cpunum); | 298 | printk(KERN_CRIT "CPU#%d already initialized!\n", cpunum); |
298 | machine_halt(); | 299 | machine_halt(); |
299 | } | 300 | } |
300 | |||
301 | notify_cpu_starting(cpunum); | ||
302 | |||
303 | set_cpu_online(cpunum, true); | 301 | set_cpu_online(cpunum, true); |
304 | 302 | ||
305 | /* Initialise the idle task for this CPU */ | 303 | /* Initialise the idle task for this CPU */ |
@@ -338,11 +336,26 @@ void __init smp_callin(void) | |||
338 | /* | 336 | /* |
339 | * Bring one cpu online. | 337 | * Bring one cpu online. |
340 | */ | 338 | */ |
341 | int __cpuinit smp_boot_one_cpu(int cpuid, struct task_struct *idle) | 339 | int __cpuinit smp_boot_one_cpu(int cpuid) |
342 | { | 340 | { |
343 | const struct cpuinfo_parisc *p = &per_cpu(cpu_data, cpuid); | 341 | const struct cpuinfo_parisc *p = &per_cpu(cpu_data, cpuid); |
342 | struct task_struct *idle; | ||
344 | long timeout; | 343 | long timeout; |
345 | 344 | ||
345 | /* | ||
346 | * Create an idle task for this CPU. Note the address wed* give | ||
347 | * to kernel_thread is irrelevant -- it's going to start | ||
348 | * where OS_BOOT_RENDEVZ vector in SAL says to start. But | ||
349 | * this gets all the other task-y sort of data structures set | ||
350 | * up like we wish. We need to pull the just created idle task | ||
351 | * off the run queue and stuff it into the init_tasks[] array. | ||
352 | * Sheesh . . . | ||
353 | */ | ||
354 | |||
355 | idle = fork_idle(cpuid); | ||
356 | if (IS_ERR(idle)) | ||
357 | panic("SMP: fork failed for CPU:%d", cpuid); | ||
358 | |||
346 | task_thread_info(idle)->cpu = cpuid; | 359 | task_thread_info(idle)->cpu = cpuid; |
347 | 360 | ||
348 | /* Let _start know what logical CPU we're booting | 361 | /* Let _start know what logical CPU we're booting |
@@ -386,6 +399,10 @@ int __cpuinit smp_boot_one_cpu(int cpuid, struct task_struct *idle) | |||
386 | udelay(100); | 399 | udelay(100); |
387 | barrier(); | 400 | barrier(); |
388 | } | 401 | } |
402 | |||
403 | put_task_struct(idle); | ||
404 | idle = NULL; | ||
405 | |||
389 | printk(KERN_CRIT "SMP: CPU:%d is stuck.\n", cpuid); | 406 | printk(KERN_CRIT "SMP: CPU:%d is stuck.\n", cpuid); |
390 | return -1; | 407 | return -1; |
391 | 408 | ||
@@ -434,10 +451,10 @@ void smp_cpus_done(unsigned int cpu_max) | |||
434 | } | 451 | } |
435 | 452 | ||
436 | 453 | ||
437 | int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle) | 454 | int __cpuinit __cpu_up(unsigned int cpu) |
438 | { | 455 | { |
439 | if (cpu != 0 && cpu < parisc_max_cpus) | 456 | if (cpu != 0 && cpu < parisc_max_cpus) |
440 | smp_boot_one_cpu(cpu, tidle); | 457 | smp_boot_one_cpu(cpu); |
441 | 458 | ||
442 | return cpu_online(cpu) ? 0 : -ENOSYS; | 459 | return cpu_online(cpu) ? 0 : -ENOSYS; |
443 | } | 460 | } |
diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c index f76c10863c6..c9b932260f4 100644 --- a/arch/parisc/kernel/sys_parisc.c +++ b/arch/parisc/kernel/sys_parisc.c | |||
@@ -73,8 +73,6 @@ static unsigned long get_shared_area(struct address_space *mapping, | |||
73 | struct vm_area_struct *vma; | 73 | struct vm_area_struct *vma; |
74 | int offset = mapping ? get_offset(mapping) : 0; | 74 | int offset = mapping ? get_offset(mapping) : 0; |
75 | 75 | ||
76 | offset = (offset + (pgoff << PAGE_SHIFT)) & 0x3FF000; | ||
77 | |||
78 | addr = DCACHE_ALIGN(addr - offset) + offset; | 76 | addr = DCACHE_ALIGN(addr - offset) + offset; |
79 | 77 | ||
80 | for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) { | 78 | for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) { |
@@ -227,12 +225,12 @@ long parisc_personality(unsigned long personality) | |||
227 | long err; | 225 | long err; |
228 | 226 | ||
229 | if (personality(current->personality) == PER_LINUX32 | 227 | if (personality(current->personality) == PER_LINUX32 |
230 | && personality(personality) == PER_LINUX) | 228 | && personality == PER_LINUX) |
231 | personality = (personality & ~PER_MASK) | PER_LINUX32; | 229 | personality = PER_LINUX32; |
232 | 230 | ||
233 | err = sys_personality(personality); | 231 | err = sys_personality(personality); |
234 | if (personality(err) == PER_LINUX32) | 232 | if (err == PER_LINUX32) |
235 | err = (err & ~PER_MASK) | PER_LINUX; | 233 | err = PER_LINUX; |
236 | 234 | ||
237 | return err; | 235 | return err; |
238 | } | 236 | } |
diff --git a/arch/parisc/kernel/sys_parisc32.c b/arch/parisc/kernel/sys_parisc32.c index 9cfdaa19ab6..dc9a6246232 100644 --- a/arch/parisc/kernel/sys_parisc32.c +++ b/arch/parisc/kernel/sys_parisc32.c | |||
@@ -53,6 +53,28 @@ | |||
53 | #define DBG(x) | 53 | #define DBG(x) |
54 | #endif | 54 | #endif |
55 | 55 | ||
56 | /* | ||
57 | * sys32_execve() executes a new program. | ||
58 | */ | ||
59 | |||
60 | asmlinkage int sys32_execve(struct pt_regs *regs) | ||
61 | { | ||
62 | int error; | ||
63 | char *filename; | ||
64 | |||
65 | DBG(("sys32_execve(%p) r26 = 0x%lx\n", regs, regs->gr[26])); | ||
66 | filename = getname((const char __user *) regs->gr[26]); | ||
67 | error = PTR_ERR(filename); | ||
68 | if (IS_ERR(filename)) | ||
69 | goto out; | ||
70 | error = compat_do_execve(filename, compat_ptr(regs->gr[25]), | ||
71 | compat_ptr(regs->gr[24]), regs); | ||
72 | putname(filename); | ||
73 | out: | ||
74 | |||
75 | return error; | ||
76 | } | ||
77 | |||
56 | asmlinkage long sys32_unimplemented(int r26, int r25, int r24, int r23, | 78 | asmlinkage long sys32_unimplemented(int r26, int r25, int r24, int r23, |
57 | int r22, int r21, int r20) | 79 | int r22, int r21, int r20) |
58 | { | 80 | { |
diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S index 86742df0b19..82a52b2fb13 100644 --- a/arch/parisc/kernel/syscall.S +++ b/arch/parisc/kernel/syscall.S | |||
@@ -156,7 +156,7 @@ linux_gateway_entry: | |||
156 | STREG %r26, TASK_PT_GR26(%r1) /* 1st argument */ | 156 | STREG %r26, TASK_PT_GR26(%r1) /* 1st argument */ |
157 | STREG %r27, TASK_PT_GR27(%r1) /* user dp */ | 157 | STREG %r27, TASK_PT_GR27(%r1) /* user dp */ |
158 | STREG %r28, TASK_PT_GR28(%r1) /* return value 0 */ | 158 | STREG %r28, TASK_PT_GR28(%r1) /* return value 0 */ |
159 | STREG %r0, TASK_PT_ORIG_R28(%r1) /* don't prohibit restarts */ | 159 | STREG %r28, TASK_PT_ORIG_R28(%r1) /* return value 0 (saved for signals) */ |
160 | STREG %r29, TASK_PT_GR29(%r1) /* return value 1 */ | 160 | STREG %r29, TASK_PT_GR29(%r1) /* return value 1 */ |
161 | STREG %r31, TASK_PT_GR31(%r1) /* preserve syscall return ptr */ | 161 | STREG %r31, TASK_PT_GR31(%r1) /* preserve syscall return ptr */ |
162 | 162 | ||
@@ -180,10 +180,9 @@ linux_gateway_entry: | |||
180 | 180 | ||
181 | /* Are we being ptraced? */ | 181 | /* Are we being ptraced? */ |
182 | mfctl %cr30, %r1 | 182 | mfctl %cr30, %r1 |
183 | LDREG TI_FLAGS(%r1),%r1 | 183 | LDREG TI_TASK(%r1),%r1 |
184 | ldi _TIF_SYSCALL_TRACE_MASK, %r19 | 184 | ldw TASK_PTRACE(%r1), %r1 |
185 | and,COND(=) %r1, %r19, %r0 | 185 | bb,<,n %r1,31,.Ltracesys |
186 | b,n .Ltracesys | ||
187 | 186 | ||
188 | /* Note! We cannot use the syscall table that is mapped | 187 | /* Note! We cannot use the syscall table that is mapped |
189 | nearby since the gateway page is mapped execute-only. */ | 188 | nearby since the gateway page is mapped execute-only. */ |
diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S index 54d950b067b..3735abd7f8f 100644 --- a/arch/parisc/kernel/syscall_table.S +++ b/arch/parisc/kernel/syscall_table.S | |||
@@ -60,13 +60,13 @@ | |||
60 | ENTRY_SAME(fork_wrapper) | 60 | ENTRY_SAME(fork_wrapper) |
61 | ENTRY_SAME(read) | 61 | ENTRY_SAME(read) |
62 | ENTRY_SAME(write) | 62 | ENTRY_SAME(write) |
63 | ENTRY_COMP(open) /* 5 */ | 63 | ENTRY_SAME(open) /* 5 */ |
64 | ENTRY_SAME(close) | 64 | ENTRY_SAME(close) |
65 | ENTRY_SAME(waitpid) | 65 | ENTRY_SAME(waitpid) |
66 | ENTRY_SAME(creat) | 66 | ENTRY_SAME(creat) |
67 | ENTRY_SAME(link) | 67 | ENTRY_SAME(link) |
68 | ENTRY_SAME(unlink) /* 10 */ | 68 | ENTRY_SAME(unlink) /* 10 */ |
69 | ENTRY_COMP(execve) | 69 | ENTRY_DIFF(execve_wrapper) |
70 | ENTRY_SAME(chdir) | 70 | ENTRY_SAME(chdir) |
71 | /* See comments in kernel/time.c!!! Maybe we don't need this? */ | 71 | /* See comments in kernel/time.c!!! Maybe we don't need this? */ |
72 | ENTRY_COMP(time) | 72 | ENTRY_COMP(time) |
diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c index 70e105d6242..45b7389d77a 100644 --- a/arch/parisc/kernel/time.c +++ b/arch/parisc/kernel/time.c | |||
@@ -29,7 +29,6 @@ | |||
29 | #include <asm/uaccess.h> | 29 | #include <asm/uaccess.h> |
30 | #include <asm/io.h> | 30 | #include <asm/io.h> |
31 | #include <asm/irq.h> | 31 | #include <asm/irq.h> |
32 | #include <asm/page.h> | ||
33 | #include <asm/param.h> | 32 | #include <asm/param.h> |
34 | #include <asm/pdc.h> | 33 | #include <asm/pdc.h> |
35 | #include <asm/led.h> | 34 | #include <asm/led.h> |
@@ -199,6 +198,8 @@ static struct clocksource clocksource_cr16 = { | |||
199 | .rating = 300, | 198 | .rating = 300, |
200 | .read = read_cr16, | 199 | .read = read_cr16, |
201 | .mask = CLOCKSOURCE_MASK(BITS_PER_LONG), | 200 | .mask = CLOCKSOURCE_MASK(BITS_PER_LONG), |
201 | .mult = 0, /* to be set */ | ||
202 | .shift = 22, | ||
202 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | 203 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, |
203 | }; | 204 | }; |
204 | 205 | ||
@@ -269,5 +270,7 @@ void __init time_init(void) | |||
269 | 270 | ||
270 | /* register at clocksource framework */ | 271 | /* register at clocksource framework */ |
271 | current_cr16_khz = PAGE0->mem_10msec/10; /* kHz */ | 272 | current_cr16_khz = PAGE0->mem_10msec/10; /* kHz */ |
272 | clocksource_register_khz(&clocksource_cr16, current_cr16_khz); | 273 | clocksource_cr16.mult = clocksource_khz2mult(current_cr16_khz, |
274 | clocksource_cr16.shift); | ||
275 | clocksource_register(&clocksource_cr16); | ||
273 | } | 276 | } |
diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c index 45ba99f5080..f19e6604026 100644 --- a/arch/parisc/kernel/traps.c +++ b/arch/parisc/kernel/traps.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/bug.h> | 27 | #include <linux/bug.h> |
28 | 28 | ||
29 | #include <asm/assembly.h> | 29 | #include <asm/assembly.h> |
30 | #include <asm/system.h> | ||
30 | #include <asm/uaccess.h> | 31 | #include <asm/uaccess.h> |
31 | #include <asm/io.h> | 32 | #include <asm/io.h> |
32 | #include <asm/irq.h> | 33 | #include <asm/irq.h> |
diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S index 64a999882e4..fa6f2b8163e 100644 --- a/arch/parisc/kernel/vmlinux.lds.S +++ b/arch/parisc/kernel/vmlinux.lds.S | |||
@@ -50,10 +50,8 @@ SECTIONS | |||
50 | . = KERNEL_BINARY_TEXT_START; | 50 | . = KERNEL_BINARY_TEXT_START; |
51 | 51 | ||
52 | _text = .; /* Text and read-only data */ | 52 | _text = .; /* Text and read-only data */ |
53 | .head ALIGN(16) : { | ||
54 | HEAD_TEXT | ||
55 | } = 0 | ||
56 | .text ALIGN(16) : { | 53 | .text ALIGN(16) : { |
54 | HEAD_TEXT | ||
57 | TEXT_TEXT | 55 | TEXT_TEXT |
58 | SCHED_TEXT | 56 | SCHED_TEXT |
59 | LOCK_TEXT | 57 | LOCK_TEXT |
@@ -67,7 +65,7 @@ SECTIONS | |||
67 | *(.fixup) | 65 | *(.fixup) |
68 | *(.lock.text) /* out-of-line lock text */ | 66 | *(.lock.text) /* out-of-line lock text */ |
69 | *(.gnu.warning) | 67 | *(.gnu.warning) |
70 | } | 68 | } = 0 |
71 | /* End of text section */ | 69 | /* End of text section */ |
72 | _etext = .; | 70 | _etext = .; |
73 | 71 | ||