aboutsummaryrefslogtreecommitdiffstats
path: root/arch/parisc/kernel
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /arch/parisc/kernel
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'arch/parisc/kernel')
-rw-r--r--arch/parisc/kernel/Makefile2
-rw-r--r--arch/parisc/kernel/cache.c4
-rw-r--r--arch/parisc/kernel/drivers.c1
-rw-r--r--arch/parisc/kernel/entry.S273
-rw-r--r--arch/parisc/kernel/firmware.c1
-rw-r--r--arch/parisc/kernel/hardware.c7
-rw-r--r--arch/parisc/kernel/module.c2
-rw-r--r--arch/parisc/kernel/pacache.S38
-rw-r--r--arch/parisc/kernel/parisc_ksyms.c1
-rw-r--r--arch/parisc/kernel/pci-dma.c3
-rw-r--r--arch/parisc/kernel/pci.c58
-rw-r--r--arch/parisc/kernel/pdc_cons.c60
-rw-r--r--arch/parisc/kernel/process.c152
-rw-r--r--arch/parisc/kernel/ptrace.c1
-rw-r--r--arch/parisc/kernel/setup.c1
-rw-r--r--arch/parisc/kernel/signal.c103
-rw-r--r--arch/parisc/kernel/signal32.c8
-rw-r--r--arch/parisc/kernel/signal32.h52
-rw-r--r--arch/parisc/kernel/smp.c35
-rw-r--r--arch/parisc/kernel/sys_parisc.c10
-rw-r--r--arch/parisc/kernel/sys_parisc32.c22
-rw-r--r--arch/parisc/kernel/syscall.S9
-rw-r--r--arch/parisc/kernel/syscall_table.S4
-rw-r--r--arch/parisc/kernel/time.c7
-rw-r--r--arch/parisc/kernel/traps.c1
-rw-r--r--arch/parisc/kernel/vmlinux.lds.S6
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
5extra-y := head.o vmlinux.lds 5extra-y := init_task.o head.o vmlinux.lds
6 6
7obj-y := cache.o pacache.o setup.o traps.o time.o irq.o \ 7obj-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
716ENTRY(__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
749ENDPROC(__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
716ENTRY(ret_from_kernel_thread) 758ENTRY(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
732ENDPROC(ret_from_kernel_thread) 785ENDPROC(ret_from_kernel_thread)
733 786
787 .import sys_execve, code
788ENTRY(__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
808ENDPROC(__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
1111dtlb_check_alias_20w: 1187dtlb_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
1135nadtlb_check_alias_20w: 1211nadtlb_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
1167dtlb_check_alias_11: 1243dtlb_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
1199nadtlb_check_alias_11: 1275nadtlb_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
1226dtlb_check_alias_20: 1302dtlb_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
1252nadtlb_check_alias_20: 1328nadtlb_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
1379naitlb_check_alias_20w: 1455naitlb_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
1433naitlb_check_alias_11: 1509naitlb_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
1479naitlb_check_alias_20: 1555naitlb_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 1767ENTRY(sys_fork_wrapper)
1692ENTRY(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)
1699ENDPROC(sys_\name\()_wrapper)
1700 .endm
1701 1773
1702fork_like clone 1774 STREG %r2,-RP_OFFSET(%r30)
1703fork_like fork 1775 ldo FRAME_SIZE(%r30),%r30
1704fork_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
1707ENTRY(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)
1710finish_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
1791wrapper_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)
1804ENDPROC(sys_fork_wrapper)
1805
1806 /* Set the return value for the child */
1807ENTRY(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
1719ENDPROC(child_return) 1815ENDPROC(child_return)
1720 1816
1817
1818ENTRY(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
1839ENDPROC(sys_clone_wrapper)
1840
1841
1842ENTRY(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
1863ENDPROC(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
1895error_\execve:
1896 bv %r0(%r19)
1897 nop
1898 .endm
1899
1900 .import sys_execve
1901ENTRY(sys_execve_wrapper)
1902 execve_wrapper sys_execve
1903ENDPROC(sys_execve_wrapper)
1904
1905#ifdef CONFIG_64BIT
1906 .import sys32_execve
1907ENTRY(sys32_execve_wrapper)
1908 execve_wrapper sys32_execve
1909ENDPROC(sys32_execve_wrapper)
1910#endif
1911
1721ENTRY(sys_rt_sigreturn_wrapper) 1912ENTRY(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
1834syscall_check_sig: 2025syscall_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
72static DEFINE_SPINLOCK(pdc_lock); 73static 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
41static struct hp_hardware hp_hardware_list[] = { 41static 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
1330const char *parisc_hardware_description(struct parisc_device_id *id) 1330const char * __devinit
1331parisc_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
215void *module_alloc(unsigned long size) 215void *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 7091: fic,m %r1(%r28)
710 * explicit space specification, so use %sr4 */ 710 fic,m %r1(%r28)
7111: 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>
47EXPORT_SYMBOL(lstrncpy_from_user);
47EXPORT_SYMBOL(lclear_user); 48EXPORT_SYMBOL(lclear_user);
48EXPORT_SYMBOL(lstrnlen_user); 49EXPORT_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
143char *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(). */
199void __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
227void 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
246EXPORT_SYMBOL(pcibios_resource_to_bus);
247EXPORT_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
56static DEFINE_SPINLOCK(pdc_console_lock); 55static 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
94static void pdc_console_poll(unsigned long unused); 93static struct timer_list pdc_console_timer;
95static DEFINE_TIMER(pdc_console_timer, pdc_console_poll, 0, 0);
96static struct tty_port tty_port;
97 94
98static int pdc_console_tty_open(struct tty_struct *tty, struct file *filp) 95static 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
106static void pdc_console_tty_close(struct tty_struct *tty, struct file *filp) 103static 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
114static int pdc_console_tty_write(struct tty_struct *tty, const unsigned char *buf, int count) 109static 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
125static struct tty_driver *pdc_console_tty_driver;
126
130static const struct tty_operations pdc_console_tty_ops = { 127static 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
138static void pdc_console_poll(unsigned long unused) 135static 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
163static struct tty_driver *pdc_console_tty_driver;
164
165static int __init pdc_console_tty_driver_init(void) 160static 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;
166EXPORT_SYMBOL(pm_power_off); 164EXPORT_SYMBOL(pm_power_off);
167 165
168/* 166/*
167 * Create a kernel thread
168 */
169
170extern pid_t __kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
171pid_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}
181EXPORT_SYMBOL(kernel_thread);
182
183/*
169 * Free current thread data structures etc.. 184 * Free current thread data structures etc..
170 */ 185 */
171void exit_thread(void) 186void 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
182void release_thread(struct task_struct *dead_task) 198void 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). */
223int
224sys_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
251int
252sys_vfork(struct pt_regs *regs)
253{
254 return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->gr[30], regs, 0, NULL, NULL);
255}
256
205int 257int
206copy_thread(unsigned long clone_flags, unsigned long usp, 258copy_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
342asmlinkage 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);
356out:
357
358 return error;
359}
360
361extern int __execve(const char *filename,
362 const char *const argv[],
363 const char *const envp[], struct task_struct *task);
364int 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
275unsigned long 371unsigned long
276get_wchan(struct task_struct *p) 372get_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(&current->sighand->siglock);
135 current->blocked = set;
136 recalc_sigpending();
137 spin_unlock_irq(&current->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
442static void 446static long
443handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, 447handle_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(&current->sighand->siglock);
458 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
459 if (!(ka->sa.sa_flags & SA_NODEFER))
460 sigaddset(&current->blocked,sig);
461 recalc_sigpending();
462 spin_unlock_irq(&current->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
462static inline void 471static inline void
463syscall_restart(struct pt_regs *regs, struct k_sigaction *ka) 472syscall_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)
492static inline void 502static inline void
493insert_restart_trampoline(struct pt_regs *regs) 503insert_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 = &current->saved_sigmask;
592 else
593 oldset = &current->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, &current->saved_sigmask, NULL);
636 }
637
638 return;
591} 639}
592 640
593void do_notify_resume(struct pt_regs *regs, long in_syscall) 641void 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
50inline void 52inline void
51sigset_32to64(sigset_t *s64, compat_sigset_t *s32) 53sigset_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
58typedef 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
58int copy_siginfo_to_user32 (compat_siginfo_t __user *to, siginfo_t *from); 110int copy_siginfo_to_user32 (compat_siginfo_t __user *to, siginfo_t *from);
59int copy_siginfo_from_user32 (siginfo_t *to, compat_siginfo_t __user *from); 111int 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 */
341int __cpuinit smp_boot_one_cpu(int cpuid, struct task_struct *idle) 339int __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
437int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle) 454int __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
60asmlinkage 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);
73out:
74
75 return error;
76}
77
56asmlinkage long sys32_unimplemented(int r26, int r25, int r24, int r23, 78asmlinkage 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