aboutsummaryrefslogtreecommitdiffstats
path: root/arch/parisc/kernel/entry.S
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2012-10-05 18:55:57 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2012-10-14 19:36:37 -0400
commitff0ab8af9c3f36e7b6f716c3b9e8811a4202eec6 (patch)
tree78f5dba557a1f91b868fa0118516562b6cd28244 /arch/parisc/kernel/entry.S
parent7f1f311ac7b7b9c779fd207a20369f7fa3a61ba6 (diff)
parisc: optimizations in copy_thread() and friends
* in user thread case the registers had been copied as part of task_struct already; no need to do it in copy_thread(). * no need to store kernel stack pointer into regs->r21; we know its offset anyway. * no need to clobber r3 in sys_fork_wrapper and friends - r28 will do just as well and *it* will be overwritten anyway. * no need to mess with storing the return address for child - it should just use syscall_exit. * no need to bother with separate stack frame for sys_clone() - just branch there and be done with that. * no need to bother with wrapper_exit - we need it only on the child_return, so let's just do it there. * use the same ksp for kernel threads and userland ones, while we are at it, and let ret_from_kernel_execve() go through the normal syscall_exit. More straightforward is better here... [fixes from jejb folded] Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'arch/parisc/kernel/entry.S')
-rw-r--r--arch/parisc/kernel/entry.S86
1 files changed, 19 insertions, 67 deletions
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S
index 7d22e97347b7..47fb6ddcf12e 100644
--- a/arch/parisc/kernel/entry.S
+++ b/arch/parisc/kernel/entry.S
@@ -719,7 +719,7 @@ ENTRY(ret_from_kernel_thread)
719 BL schedule_tail, %r2 719 BL schedule_tail, %r2
720 nop 720 nop
721 721
722 LDREG TI_TASK-THREAD_SZ_ALGN(%r30), %r1 722 LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1
723 LDREG TASK_PT_GR25(%r1), %r26 723 LDREG TASK_PT_GR25(%r1), %r26
724#ifdef CONFIG_64BIT 724#ifdef CONFIG_64BIT
725 LDREG TASK_PT_GR27(%r1), %r27 725 LDREG TASK_PT_GR27(%r1), %r27
@@ -743,9 +743,8 @@ ENDPROC(ret_from_kernel_thread)
743 743
744ENTRY(ret_from_kernel_execve) 744ENTRY(ret_from_kernel_execve)
745 mfctl %cr30, %r1 745 mfctl %cr30, %r1
746 ldo THREAD_SZ_ALGN(%r1), %r30 746 b syscall_exit /* forward */
747 b intr_return /* forward */ 747 ldo THREAD_SZ_ALGN+FRAME_SIZE(%r1), %r30
748 copy %r26,%r16 /* pt_regs into r16 */
749ENDPROC(ret_from_kernel_execve) 748ENDPROC(ret_from_kernel_execve)
750 749
751 750
@@ -1709,39 +1708,13 @@ ENTRY(sys_fork_wrapper)
1709 LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1 1708 LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1
1710 ldo TASK_REGS(%r1),%r1 1709 ldo TASK_REGS(%r1),%r1
1711 reg_save %r1 1710 reg_save %r1
1712 mfctl %cr27, %r3 1711 mfctl %cr27, %r28
1713 STREG %r3, PT_CR27(%r1) 1712 STREG %r28, PT_CR27(%r1)
1714
1715 STREG %r2,-RP_OFFSET(%r30)
1716 ldo FRAME_SIZE(%r30),%r30
1717#ifdef CONFIG_64BIT
1718 ldo -16(%r30),%r29 /* Reference param save area */
1719#endif
1720
1721 /* These are call-clobbered registers and therefore
1722 also syscall-clobbered (we hope). */
1723 STREG %r2,PT_GR19(%r1) /* save for child */
1724 STREG %r30,PT_GR21(%r1)
1725 1713
1726 LDREG PT_GR30(%r1),%r25 1714 LDREG PT_GR30(%r1),%r25
1727 copy %r1,%r24 1715 copy %r1,%r24
1728 BL sys_clone,%r2 1716 b sys_clone
1729 ldi SIGCHLD,%r26 1717 ldi SIGCHLD,%r26
1730
1731 LDREG -RP_OFFSET-FRAME_SIZE(%r30),%r2
1732wrapper_exit:
1733 ldo -FRAME_SIZE(%r30),%r30 /* get the stackframe */
1734 LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
1735 ldo TASK_REGS(%r1),%r1 /* get pt regs */
1736
1737 LDREG PT_CR27(%r1), %r3
1738 mtctl %r3, %cr27
1739 reg_restore %r1
1740
1741 /* strace expects syscall # to be preserved in r20 */
1742 ldi __NR_fork,%r20
1743 bv %r0(%r2)
1744 STREG %r20,PT_GR20(%r1)
1745ENDPROC(sys_fork_wrapper) 1718ENDPROC(sys_fork_wrapper)
1746 1719
1747 /* Set the return value for the child */ 1720 /* Set the return value for the child */
@@ -1749,9 +1722,13 @@ ENTRY(child_return)
1749 BL schedule_tail, %r2 1722 BL schedule_tail, %r2
1750 nop 1723 nop
1751 1724
1752 LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE-FRAME_SIZE(%r30), %r1 1725 LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1
1753 LDREG TASK_PT_GR19(%r1),%r2 1726 ldo TASK_REGS(%r1),%r1 /* get pt regs */
1754 b wrapper_exit 1727
1728 LDREG PT_CR27(%r1), %r3
1729 mtctl %r3, %cr27
1730 reg_restore %r1
1731 b syscall_exit
1755 copy %r0,%r28 1732 copy %r0,%r28
1756ENDPROC(child_return) 1733ENDPROC(child_return)
1757 1734
@@ -1760,23 +1737,10 @@ ENTRY(sys_clone_wrapper)
1760 LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 1737 LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
1761 ldo TASK_REGS(%r1),%r1 /* get pt regs */ 1738 ldo TASK_REGS(%r1),%r1 /* get pt regs */
1762 reg_save %r1 1739 reg_save %r1
1763 mfctl %cr27, %r3 1740 mfctl %cr27, %r28
1764 STREG %r3, PT_CR27(%r1) 1741 STREG %r28, PT_CR27(%r1)
1765 1742 b sys_clone
1766 STREG %r2,-RP_OFFSET(%r30)
1767 ldo FRAME_SIZE(%r30),%r30
1768#ifdef CONFIG_64BIT
1769 ldo -16(%r30),%r29 /* Reference param save area */
1770#endif
1771
1772 /* WARNING - Clobbers r19 and r21, userspace must save these! */
1773 STREG %r2,PT_GR19(%r1) /* save for child */
1774 STREG %r30,PT_GR21(%r1)
1775 BL sys_clone,%r2
1776 copy %r1,%r24 1743 copy %r1,%r24
1777
1778 b wrapper_exit
1779 LDREG -RP_OFFSET-FRAME_SIZE(%r30),%r2
1780ENDPROC(sys_clone_wrapper) 1744ENDPROC(sys_clone_wrapper)
1781 1745
1782 1746
@@ -1784,23 +1748,11 @@ ENTRY(sys_vfork_wrapper)
1784 LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 1748 LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
1785 ldo TASK_REGS(%r1),%r1 /* get pt regs */ 1749 ldo TASK_REGS(%r1),%r1 /* get pt regs */
1786 reg_save %r1 1750 reg_save %r1
1787 mfctl %cr27, %r3 1751 mfctl %cr27, %r28
1788 STREG %r3, PT_CR27(%r1) 1752 STREG %r28, PT_CR27(%r1)
1789
1790 STREG %r2,-RP_OFFSET(%r30)
1791 ldo FRAME_SIZE(%r30),%r30
1792#ifdef CONFIG_64BIT
1793 ldo -16(%r30),%r29 /* Reference param save area */
1794#endif
1795 1753
1796 STREG %r2,PT_GR19(%r1) /* save for child */ 1754 b sys_vfork
1797 STREG %r30,PT_GR21(%r1)
1798
1799 BL sys_vfork,%r2
1800 copy %r1,%r26 1755 copy %r1,%r26
1801
1802 b wrapper_exit
1803 LDREG -RP_OFFSET-FRAME_SIZE(%r30),%r2
1804ENDPROC(sys_vfork_wrapper) 1756ENDPROC(sys_vfork_wrapper)
1805 1757
1806 1758