From: Ingo Molnar <[EMAIL PROTECTED]>

provide an optimized assembly version of the copy_uatom() method.
This is about 3 times faster than the C version.

Signed-off-by: Ingo Molnar <[EMAIL PROTECTED]>
Signed-off-by: Arjan van de Ven <[EMAIL PROTECTED]>
---
 arch/i386/lib/getuser.S |  115 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 115 insertions(+)

Index: linux/arch/i386/lib/getuser.S
===================================================================
--- linux.orig/arch/i386/lib/getuser.S
+++ linux/arch/i386/lib/getuser.S
@@ -10,6 +10,121 @@
  */
 #include <asm/thread_info.h>
 
+/*
+ * copy_uatom() - copy a syslet_atom from user-space into kernel-space:
+ */
+
+.text
+.align 4
+.globl copy_uatom
+copy_uatom:
+       #
+       # regparm(2) call, %eax: atom, %edx: uatom
+       #
+       movl %eax, %ecx                 # %ecx is atom, %edx remains uatom
+
+       cmpl $__PAGE_OFFSET-40, %edx    # access_ok(uatom-sizeof(*uatom))
+       jae bad_copy_uatom
+
+
+1:     movl (%edx), %eax               # atom->flags = uatom->flags
+       movl %eax, (%ecx)
+
+2:     movl 4(%edx), %eax              # atom->nr = uatom->nr
+       movl %eax, 4(%ecx)
+
+3:     movl 8(%edx), %eax              # atom->ret_ptr = uatom->ret_ptr
+       movl %eax, 8(%ecx)
+
+4:     movl 12(%edx), %eax             # atom->next = uatom->next
+       movl %eax, 12(%ecx)
+
+
+10:    movl 16(%edx), %eax             # atom->arg_ptr[0] = uatom->arg_ptr[0]
+       testl %eax, %eax
+       jz 20f                          # NULL ptr - zero out remaining args
+       cmpl $__PAGE_OFFSET, %eax       # access_ok(arg_ptr)
+       jae bad_copy_uatom
+100:   movl (%eax), %eax
+       movl %eax, 16(%ecx)
+
+11:    movl 20(%edx), %eax             # atom->arg_ptr[1] = uatom->arg_ptr[1]
+       testl %eax, %eax
+       jz 21f                          # NULL ptr - zero out remaining args
+       cmpl $__PAGE_OFFSET, %eax       # access_ok(arg_ptr)
+       jae bad_copy_uatom
+110:   movl (%eax), %eax
+       movl %eax, 20(%ecx)
+
+12:    movl 24(%edx), %eax             # atom->arg_ptr[2] = uatom->arg_ptr[2]
+       testl %eax, %eax
+       jz 22f                          # NULL ptr - zero out remaining args
+       cmpl $__PAGE_OFFSET, %eax       # access_ok(arg_ptr)
+       jae bad_copy_uatom
+120:   movl (%eax), %eax
+       movl %eax, 24(%ecx)
+
+13:    movl 28(%edx), %eax             # atom->arg_ptr[3] = uatom->arg_ptr[3]
+       testl %eax, %eax
+       jz 23f                          # NULL ptr - zero out remaining args
+       cmpl $__PAGE_OFFSET, %eax       # access_ok(arg_ptr)
+       jae bad_copy_uatom
+130:   movl (%eax), %eax
+       movl %eax, 28(%ecx)
+
+14:    movl 32(%edx), %eax             # atom->arg_ptr[4] = uatom->arg_ptr[4]
+       testl %eax, %eax
+       jz 24f                          # NULL ptr - zero out remaining args
+       cmpl $__PAGE_OFFSET, %eax       # access_ok(arg_ptr)
+       jae bad_copy_uatom
+140:   movl (%eax), %eax
+       movl %eax, 32(%ecx)
+
+15:    movl 36(%edx), %eax             # atom->arg_ptr[5] = uatom->arg_ptr[5]
+       testl %eax, %eax
+       jz 25f                          # NULL ptr - zero out remaining args
+       cmpl $__PAGE_OFFSET, %eax       # access_ok(arg_ptr)
+       jae bad_copy_uatom
+150:   movl (%eax), %eax
+       movl %eax, 36(%ecx)
+
+       xorl %eax, %eax                 # return 0
+       ret
+
+       #
+       # Zero out arg values. Since ptr was NULL, %eax is zero:
+       #
+20:    movl %eax, 16(%ecx)             # atom->args[0] = 0
+21:    movl %eax, 20(%ecx)             # atom->args[1] = 0
+22:    movl %eax, 24(%ecx)             # atom->args[2] = 0
+23:    movl %eax, 28(%ecx)             # atom->args[3] = 0
+24:    movl %eax, 32(%ecx)             # atom->args[4] = 0
+25:    movl %eax, 36(%ecx)             # atom->args[5] = 0
+
+       ret                             # return 0
+
+bad_copy_uatom:
+       movl $-14, %eax
+       ret
+
+.section __ex_table,"a"
+       .long 1b,   bad_copy_uatom
+       .long 2b,   bad_copy_uatom
+       .long 3b,   bad_copy_uatom
+       .long 4b,   bad_copy_uatom
+       .long 10b,  bad_copy_uatom
+       .long 100b, bad_copy_uatom
+       .long 11b,  bad_copy_uatom
+       .long 110b, bad_copy_uatom
+       .long 12b,  bad_copy_uatom
+       .long 120b, bad_copy_uatom
+       .long 13b,  bad_copy_uatom
+       .long 130b, bad_copy_uatom
+       .long 14b,  bad_copy_uatom
+       .long 140b, bad_copy_uatom
+       .long 15b,  bad_copy_uatom
+       .long 150b, bad_copy_uatom
+.previous
 
 /*
  * __get_user_X
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to