diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2012-10-05 18:55:57 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-10-14 19:36:37 -0400 |
commit | ff0ab8af9c3f36e7b6f716c3b9e8811a4202eec6 (patch) | |
tree | 78f5dba557a1f91b868fa0118516562b6cd28244 /arch/parisc/kernel/entry.S | |
parent | 7f1f311ac7b7b9c779fd207a20369f7fa3a61ba6 (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.S | 86 |
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 | ||
744 | ENTRY(ret_from_kernel_execve) | 744 | ENTRY(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 */ | ||
749 | ENDPROC(ret_from_kernel_execve) | 748 | ENDPROC(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 | ||
1732 | wrapper_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) | ||
1745 | ENDPROC(sys_fork_wrapper) | 1718 | ENDPROC(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 |
1756 | ENDPROC(child_return) | 1733 | ENDPROC(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 | ||
1780 | ENDPROC(sys_clone_wrapper) | 1744 | ENDPROC(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 | ||
1804 | ENDPROC(sys_vfork_wrapper) | 1756 | ENDPROC(sys_vfork_wrapper) |
1805 | 1757 | ||
1806 | 1758 | ||