aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386
diff options
context:
space:
mode:
Diffstat (limited to 'arch/i386')
-rw-r--r--arch/i386/lib/usercopy.c119
1 files changed, 119 insertions, 0 deletions
diff --git a/arch/i386/lib/usercopy.c b/arch/i386/lib/usercopy.c
index 6979297ce278..c5aa65f7c02a 100644
--- a/arch/i386/lib/usercopy.c
+++ b/arch/i386/lib/usercopy.c
@@ -528,6 +528,97 @@ static unsigned long __copy_user_zeroing_intel_nocache(void *to,
528 return size; 528 return size;
529} 529}
530 530
531static unsigned long __copy_user_intel_nocache(void *to,
532 const void __user *from, unsigned long size)
533{
534 int d0, d1;
535
536 __asm__ __volatile__(
537 " .align 2,0x90\n"
538 "0: movl 32(%4), %%eax\n"
539 " cmpl $67, %0\n"
540 " jbe 2f\n"
541 "1: movl 64(%4), %%eax\n"
542 " .align 2,0x90\n"
543 "2: movl 0(%4), %%eax\n"
544 "21: movl 4(%4), %%edx\n"
545 " movnti %%eax, 0(%3)\n"
546 " movnti %%edx, 4(%3)\n"
547 "3: movl 8(%4), %%eax\n"
548 "31: movl 12(%4),%%edx\n"
549 " movnti %%eax, 8(%3)\n"
550 " movnti %%edx, 12(%3)\n"
551 "4: movl 16(%4), %%eax\n"
552 "41: movl 20(%4), %%edx\n"
553 " movnti %%eax, 16(%3)\n"
554 " movnti %%edx, 20(%3)\n"
555 "10: movl 24(%4), %%eax\n"
556 "51: movl 28(%4), %%edx\n"
557 " movnti %%eax, 24(%3)\n"
558 " movnti %%edx, 28(%3)\n"
559 "11: movl 32(%4), %%eax\n"
560 "61: movl 36(%4), %%edx\n"
561 " movnti %%eax, 32(%3)\n"
562 " movnti %%edx, 36(%3)\n"
563 "12: movl 40(%4), %%eax\n"
564 "71: movl 44(%4), %%edx\n"
565 " movnti %%eax, 40(%3)\n"
566 " movnti %%edx, 44(%3)\n"
567 "13: movl 48(%4), %%eax\n"
568 "81: movl 52(%4), %%edx\n"
569 " movnti %%eax, 48(%3)\n"
570 " movnti %%edx, 52(%3)\n"
571 "14: movl 56(%4), %%eax\n"
572 "91: movl 60(%4), %%edx\n"
573 " movnti %%eax, 56(%3)\n"
574 " movnti %%edx, 60(%3)\n"
575 " addl $-64, %0\n"
576 " addl $64, %4\n"
577 " addl $64, %3\n"
578 " cmpl $63, %0\n"
579 " ja 0b\n"
580 " sfence \n"
581 "5: movl %0, %%eax\n"
582 " shrl $2, %0\n"
583 " andl $3, %%eax\n"
584 " cld\n"
585 "6: rep; movsl\n"
586 " movl %%eax,%0\n"
587 "7: rep; movsb\n"
588 "8:\n"
589 ".section .fixup,\"ax\"\n"
590 "9: lea 0(%%eax,%0,4),%0\n"
591 "16: jmp 8b\n"
592 ".previous\n"
593 ".section __ex_table,\"a\"\n"
594 " .align 4\n"
595 " .long 0b,16b\n"
596 " .long 1b,16b\n"
597 " .long 2b,16b\n"
598 " .long 21b,16b\n"
599 " .long 3b,16b\n"
600 " .long 31b,16b\n"
601 " .long 4b,16b\n"
602 " .long 41b,16b\n"
603 " .long 10b,16b\n"
604 " .long 51b,16b\n"
605 " .long 11b,16b\n"
606 " .long 61b,16b\n"
607 " .long 12b,16b\n"
608 " .long 71b,16b\n"
609 " .long 13b,16b\n"
610 " .long 81b,16b\n"
611 " .long 14b,16b\n"
612 " .long 91b,16b\n"
613 " .long 6b,9b\n"
614 " .long 7b,16b\n"
615 ".previous"
616 : "=&c"(size), "=&D" (d0), "=&S" (d1)
617 : "1"(to), "2"(from), "0"(size)
618 : "eax", "edx", "memory");
619 return size;
620}
621
531#else 622#else
532 623
533/* 624/*
@@ -694,6 +785,19 @@ unsigned long __copy_from_user_ll(void *to, const void __user *from,
694} 785}
695EXPORT_SYMBOL(__copy_from_user_ll); 786EXPORT_SYMBOL(__copy_from_user_ll);
696 787
788unsigned long __copy_from_user_ll_nozero(void *to, const void __user *from,
789 unsigned long n)
790{
791 BUG_ON((long)n < 0);
792 if (movsl_is_ok(to, from, n))
793 __copy_user(to, from, n);
794 else
795 n = __copy_user_intel((void __user *)to,
796 (const void *)from, n);
797 return n;
798}
799EXPORT_SYMBOL(__copy_from_user_ll_nozero);
800
697unsigned long __copy_from_user_ll_nocache(void *to, const void __user *from, 801unsigned long __copy_from_user_ll_nocache(void *to, const void __user *from,
698 unsigned long n) 802 unsigned long n)
699{ 803{
@@ -709,6 +813,21 @@ unsigned long __copy_from_user_ll_nocache(void *to, const void __user *from,
709 return n; 813 return n;
710} 814}
711 815
816unsigned long __copy_from_user_ll_nocache_nozero(void *to, const void __user *from,
817 unsigned long n)
818{
819 BUG_ON((long)n < 0);
820#ifdef CONFIG_X86_INTEL_USERCOPY
821 if ( n > 64 && cpu_has_xmm2)
822 n = __copy_user_intel_nocache(to, from, n);
823 else
824 __copy_user(to, from, n);
825#else
826 __copy_user(to, from, n);
827#endif
828 return n;
829}
830
712/** 831/**
713 * copy_to_user: - Copy a block of data into user space. 832 * copy_to_user: - Copy a block of data into user space.
714 * @to: Destination address, in user space. 833 * @to: Destination address, in user space.