diff options
Diffstat (limited to 'include/asm-s390')
-rw-r--r-- | include/asm-s390/atomic.h | 8 | ||||
-rw-r--r-- | include/asm-s390/bitops.h | 440 | ||||
-rw-r--r-- | include/asm-s390/cpcmd.h | 18 | ||||
-rw-r--r-- | include/asm-s390/debug.h | 48 | ||||
-rw-r--r-- | include/asm-s390/emergency-restart.h | 6 | ||||
-rw-r--r-- | include/asm-s390/kexec.h | 42 | ||||
-rw-r--r-- | include/asm-s390/lowcore.h | 11 | ||||
-rw-r--r-- | include/asm-s390/processor.h | 57 | ||||
-rw-r--r-- | include/asm-s390/ptrace.h | 2 | ||||
-rw-r--r-- | include/asm-s390/spinlock.h | 252 | ||||
-rw-r--r-- | include/asm-s390/system.h | 38 | ||||
-rw-r--r-- | include/asm-s390/thread_info.h | 4 | ||||
-rw-r--r-- | include/asm-s390/uaccess.h | 21 | ||||
-rw-r--r-- | include/asm-s390/unistd.h | 9 |
14 files changed, 376 insertions, 580 deletions
diff --git a/include/asm-s390/atomic.h b/include/asm-s390/atomic.h index d5a05cf47168..9d86ba6f12d0 100644 --- a/include/asm-s390/atomic.h +++ b/include/asm-s390/atomic.h | |||
@@ -123,19 +123,19 @@ typedef struct { | |||
123 | #define atomic64_read(v) ((v)->counter) | 123 | #define atomic64_read(v) ((v)->counter) |
124 | #define atomic64_set(v,i) (((v)->counter) = (i)) | 124 | #define atomic64_set(v,i) (((v)->counter) = (i)) |
125 | 125 | ||
126 | static __inline__ void atomic64_add(int i, atomic64_t * v) | 126 | static __inline__ void atomic64_add(long long i, atomic64_t * v) |
127 | { | 127 | { |
128 | __CSG_LOOP(v, i, "agr"); | 128 | __CSG_LOOP(v, i, "agr"); |
129 | } | 129 | } |
130 | static __inline__ long long atomic64_add_return(int i, atomic64_t * v) | 130 | static __inline__ long long atomic64_add_return(long long i, atomic64_t * v) |
131 | { | 131 | { |
132 | return __CSG_LOOP(v, i, "agr"); | 132 | return __CSG_LOOP(v, i, "agr"); |
133 | } | 133 | } |
134 | static __inline__ long long atomic64_add_negative(int i, atomic64_t * v) | 134 | static __inline__ long long atomic64_add_negative(long long i, atomic64_t * v) |
135 | { | 135 | { |
136 | return __CSG_LOOP(v, i, "agr") < 0; | 136 | return __CSG_LOOP(v, i, "agr") < 0; |
137 | } | 137 | } |
138 | static __inline__ void atomic64_sub(int i, atomic64_t * v) | 138 | static __inline__ void atomic64_sub(long long i, atomic64_t * v) |
139 | { | 139 | { |
140 | __CSG_LOOP(v, i, "sgr"); | 140 | __CSG_LOOP(v, i, "sgr"); |
141 | } | 141 | } |
diff --git a/include/asm-s390/bitops.h b/include/asm-s390/bitops.h index 16bb08499c7f..8651524217fd 100644 --- a/include/asm-s390/bitops.h +++ b/include/asm-s390/bitops.h | |||
@@ -527,13 +527,64 @@ __constant_test_bit(unsigned long nr, const volatile unsigned long *addr) { | |||
527 | __constant_test_bit((nr),(addr)) : \ | 527 | __constant_test_bit((nr),(addr)) : \ |
528 | __test_bit((nr),(addr)) ) | 528 | __test_bit((nr),(addr)) ) |
529 | 529 | ||
530 | #ifndef __s390x__ | 530 | /* |
531 | * ffz = Find First Zero in word. Undefined if no zero exists, | ||
532 | * so code should check against ~0UL first.. | ||
533 | */ | ||
534 | static inline unsigned long ffz(unsigned long word) | ||
535 | { | ||
536 | unsigned long bit = 0; | ||
537 | |||
538 | #ifdef __s390x__ | ||
539 | if (likely((word & 0xffffffff) == 0xffffffff)) { | ||
540 | word >>= 32; | ||
541 | bit += 32; | ||
542 | } | ||
543 | #endif | ||
544 | if (likely((word & 0xffff) == 0xffff)) { | ||
545 | word >>= 16; | ||
546 | bit += 16; | ||
547 | } | ||
548 | if (likely((word & 0xff) == 0xff)) { | ||
549 | word >>= 8; | ||
550 | bit += 8; | ||
551 | } | ||
552 | return bit + _zb_findmap[word & 0xff]; | ||
553 | } | ||
554 | |||
555 | /* | ||
556 | * __ffs = find first bit in word. Undefined if no bit exists, | ||
557 | * so code should check against 0UL first.. | ||
558 | */ | ||
559 | static inline unsigned long __ffs (unsigned long word) | ||
560 | { | ||
561 | unsigned long bit = 0; | ||
562 | |||
563 | #ifdef __s390x__ | ||
564 | if (likely((word & 0xffffffff) == 0)) { | ||
565 | word >>= 32; | ||
566 | bit += 32; | ||
567 | } | ||
568 | #endif | ||
569 | if (likely((word & 0xffff) == 0)) { | ||
570 | word >>= 16; | ||
571 | bit += 16; | ||
572 | } | ||
573 | if (likely((word & 0xff) == 0)) { | ||
574 | word >>= 8; | ||
575 | bit += 8; | ||
576 | } | ||
577 | return bit + _sb_findmap[word & 0xff]; | ||
578 | } | ||
531 | 579 | ||
532 | /* | 580 | /* |
533 | * Find-bit routines.. | 581 | * Find-bit routines.. |
534 | */ | 582 | */ |
583 | |||
584 | #ifndef __s390x__ | ||
585 | |||
535 | static inline int | 586 | static inline int |
536 | find_first_zero_bit(const unsigned long * addr, unsigned int size) | 587 | find_first_zero_bit(const unsigned long * addr, unsigned long size) |
537 | { | 588 | { |
538 | typedef struct { long _[__BITOPS_WORDS(size)]; } addrtype; | 589 | typedef struct { long _[__BITOPS_WORDS(size)]; } addrtype; |
539 | unsigned long cmp, count; | 590 | unsigned long cmp, count; |
@@ -548,7 +599,7 @@ find_first_zero_bit(const unsigned long * addr, unsigned int size) | |||
548 | " srl %2,5\n" | 599 | " srl %2,5\n" |
549 | "0: c %1,0(%0,%4)\n" | 600 | "0: c %1,0(%0,%4)\n" |
550 | " jne 1f\n" | 601 | " jne 1f\n" |
551 | " ahi %0,4\n" | 602 | " la %0,4(%0)\n" |
552 | " brct %2,0b\n" | 603 | " brct %2,0b\n" |
553 | " lr %0,%3\n" | 604 | " lr %0,%3\n" |
554 | " j 4f\n" | 605 | " j 4f\n" |
@@ -574,7 +625,7 @@ find_first_zero_bit(const unsigned long * addr, unsigned int size) | |||
574 | } | 625 | } |
575 | 626 | ||
576 | static inline int | 627 | static inline int |
577 | find_first_bit(const unsigned long * addr, unsigned int size) | 628 | find_first_bit(const unsigned long * addr, unsigned long size) |
578 | { | 629 | { |
579 | typedef struct { long _[__BITOPS_WORDS(size)]; } addrtype; | 630 | typedef struct { long _[__BITOPS_WORDS(size)]; } addrtype; |
580 | unsigned long cmp, count; | 631 | unsigned long cmp, count; |
@@ -589,7 +640,7 @@ find_first_bit(const unsigned long * addr, unsigned int size) | |||
589 | " srl %2,5\n" | 640 | " srl %2,5\n" |
590 | "0: c %1,0(%0,%4)\n" | 641 | "0: c %1,0(%0,%4)\n" |
591 | " jne 1f\n" | 642 | " jne 1f\n" |
592 | " ahi %0,4\n" | 643 | " la %0,4(%0)\n" |
593 | " brct %2,0b\n" | 644 | " brct %2,0b\n" |
594 | " lr %0,%3\n" | 645 | " lr %0,%3\n" |
595 | " j 4f\n" | 646 | " j 4f\n" |
@@ -614,89 +665,8 @@ find_first_bit(const unsigned long * addr, unsigned int size) | |||
614 | return (res < size) ? res : size; | 665 | return (res < size) ? res : size; |
615 | } | 666 | } |
616 | 667 | ||
617 | static inline int | ||
618 | find_next_zero_bit (const unsigned long * addr, int size, int offset) | ||
619 | { | ||
620 | unsigned long * p = ((unsigned long *) addr) + (offset >> 5); | ||
621 | unsigned long bitvec, reg; | ||
622 | int set, bit = offset & 31, res; | ||
623 | |||
624 | if (bit) { | ||
625 | /* | ||
626 | * Look for zero in first word | ||
627 | */ | ||
628 | bitvec = (*p) >> bit; | ||
629 | __asm__(" slr %0,%0\n" | ||
630 | " lhi %2,0xff\n" | ||
631 | " tml %1,0xffff\n" | ||
632 | " jno 0f\n" | ||
633 | " ahi %0,16\n" | ||
634 | " srl %1,16\n" | ||
635 | "0: tml %1,0x00ff\n" | ||
636 | " jno 1f\n" | ||
637 | " ahi %0,8\n" | ||
638 | " srl %1,8\n" | ||
639 | "1: nr %1,%2\n" | ||
640 | " ic %1,0(%1,%3)\n" | ||
641 | " alr %0,%1" | ||
642 | : "=&d" (set), "+a" (bitvec), "=&d" (reg) | ||
643 | : "a" (&_zb_findmap) : "cc" ); | ||
644 | if (set < (32 - bit)) | ||
645 | return set + offset; | ||
646 | offset += 32 - bit; | ||
647 | p++; | ||
648 | } | ||
649 | /* | ||
650 | * No zero yet, search remaining full words for a zero | ||
651 | */ | ||
652 | res = find_first_zero_bit (p, size - 32 * (p - (unsigned long *) addr)); | ||
653 | return (offset + res); | ||
654 | } | ||
655 | |||
656 | static inline int | ||
657 | find_next_bit (const unsigned long * addr, int size, int offset) | ||
658 | { | ||
659 | unsigned long * p = ((unsigned long *) addr) + (offset >> 5); | ||
660 | unsigned long bitvec, reg; | ||
661 | int set, bit = offset & 31, res; | ||
662 | |||
663 | if (bit) { | ||
664 | /* | ||
665 | * Look for set bit in first word | ||
666 | */ | ||
667 | bitvec = (*p) >> bit; | ||
668 | __asm__(" slr %0,%0\n" | ||
669 | " lhi %2,0xff\n" | ||
670 | " tml %1,0xffff\n" | ||
671 | " jnz 0f\n" | ||
672 | " ahi %0,16\n" | ||
673 | " srl %1,16\n" | ||
674 | "0: tml %1,0x00ff\n" | ||
675 | " jnz 1f\n" | ||
676 | " ahi %0,8\n" | ||
677 | " srl %1,8\n" | ||
678 | "1: nr %1,%2\n" | ||
679 | " ic %1,0(%1,%3)\n" | ||
680 | " alr %0,%1" | ||
681 | : "=&d" (set), "+a" (bitvec), "=&d" (reg) | ||
682 | : "a" (&_sb_findmap) : "cc" ); | ||
683 | if (set < (32 - bit)) | ||
684 | return set + offset; | ||
685 | offset += 32 - bit; | ||
686 | p++; | ||
687 | } | ||
688 | /* | ||
689 | * No set bit yet, search remaining full words for a bit | ||
690 | */ | ||
691 | res = find_first_bit (p, size - 32 * (p - (unsigned long *) addr)); | ||
692 | return (offset + res); | ||
693 | } | ||
694 | |||
695 | #else /* __s390x__ */ | 668 | #else /* __s390x__ */ |
696 | 669 | ||
697 | /* | ||
698 | * Find-bit routines.. | ||
699 | */ | ||
700 | static inline unsigned long | 670 | static inline unsigned long |
701 | find_first_zero_bit(const unsigned long * addr, unsigned long size) | 671 | find_first_zero_bit(const unsigned long * addr, unsigned long size) |
702 | { | 672 | { |
@@ -712,7 +682,7 @@ find_first_zero_bit(const unsigned long * addr, unsigned long size) | |||
712 | " srlg %2,%2,6\n" | 682 | " srlg %2,%2,6\n" |
713 | "0: cg %1,0(%0,%4)\n" | 683 | "0: cg %1,0(%0,%4)\n" |
714 | " jne 1f\n" | 684 | " jne 1f\n" |
715 | " aghi %0,8\n" | 685 | " la %0,8(%0)\n" |
716 | " brct %2,0b\n" | 686 | " brct %2,0b\n" |
717 | " lgr %0,%3\n" | 687 | " lgr %0,%3\n" |
718 | " j 5f\n" | 688 | " j 5f\n" |
@@ -785,143 +755,66 @@ find_first_bit(const unsigned long * addr, unsigned long size) | |||
785 | return (res < size) ? res : size; | 755 | return (res < size) ? res : size; |
786 | } | 756 | } |
787 | 757 | ||
788 | static inline unsigned long | ||
789 | find_next_zero_bit (const unsigned long * addr, unsigned long size, unsigned long offset) | ||
790 | { | ||
791 | unsigned long * p = ((unsigned long *) addr) + (offset >> 6); | ||
792 | unsigned long bitvec, reg; | ||
793 | unsigned long set, bit = offset & 63, res; | ||
794 | |||
795 | if (bit) { | ||
796 | /* | ||
797 | * Look for zero in first word | ||
798 | */ | ||
799 | bitvec = (*p) >> bit; | ||
800 | __asm__(" lhi %2,-1\n" | ||
801 | " slgr %0,%0\n" | ||
802 | " clr %1,%2\n" | ||
803 | " jne 0f\n" | ||
804 | " aghi %0,32\n" | ||
805 | " srlg %1,%1,32\n" | ||
806 | "0: lghi %2,0xff\n" | ||
807 | " tmll %1,0xffff\n" | ||
808 | " jno 1f\n" | ||
809 | " aghi %0,16\n" | ||
810 | " srlg %1,%1,16\n" | ||
811 | "1: tmll %1,0x00ff\n" | ||
812 | " jno 2f\n" | ||
813 | " aghi %0,8\n" | ||
814 | " srlg %1,%1,8\n" | ||
815 | "2: ngr %1,%2\n" | ||
816 | " ic %1,0(%1,%3)\n" | ||
817 | " algr %0,%1" | ||
818 | : "=&d" (set), "+a" (bitvec), "=&d" (reg) | ||
819 | : "a" (&_zb_findmap) : "cc" ); | ||
820 | if (set < (64 - bit)) | ||
821 | return set + offset; | ||
822 | offset += 64 - bit; | ||
823 | p++; | ||
824 | } | ||
825 | /* | ||
826 | * No zero yet, search remaining full words for a zero | ||
827 | */ | ||
828 | res = find_first_zero_bit (p, size - 64 * (p - (unsigned long *) addr)); | ||
829 | return (offset + res); | ||
830 | } | ||
831 | |||
832 | static inline unsigned long | ||
833 | find_next_bit (const unsigned long * addr, unsigned long size, unsigned long offset) | ||
834 | { | ||
835 | unsigned long * p = ((unsigned long *) addr) + (offset >> 6); | ||
836 | unsigned long bitvec, reg; | ||
837 | unsigned long set, bit = offset & 63, res; | ||
838 | |||
839 | if (bit) { | ||
840 | /* | ||
841 | * Look for zero in first word | ||
842 | */ | ||
843 | bitvec = (*p) >> bit; | ||
844 | __asm__(" slgr %0,%0\n" | ||
845 | " ltr %1,%1\n" | ||
846 | " jnz 0f\n" | ||
847 | " aghi %0,32\n" | ||
848 | " srlg %1,%1,32\n" | ||
849 | "0: lghi %2,0xff\n" | ||
850 | " tmll %1,0xffff\n" | ||
851 | " jnz 1f\n" | ||
852 | " aghi %0,16\n" | ||
853 | " srlg %1,%1,16\n" | ||
854 | "1: tmll %1,0x00ff\n" | ||
855 | " jnz 2f\n" | ||
856 | " aghi %0,8\n" | ||
857 | " srlg %1,%1,8\n" | ||
858 | "2: ngr %1,%2\n" | ||
859 | " ic %1,0(%1,%3)\n" | ||
860 | " algr %0,%1" | ||
861 | : "=&d" (set), "+a" (bitvec), "=&d" (reg) | ||
862 | : "a" (&_sb_findmap) : "cc" ); | ||
863 | if (set < (64 - bit)) | ||
864 | return set + offset; | ||
865 | offset += 64 - bit; | ||
866 | p++; | ||
867 | } | ||
868 | /* | ||
869 | * No set bit yet, search remaining full words for a bit | ||
870 | */ | ||
871 | res = find_first_bit (p, size - 64 * (p - (unsigned long *) addr)); | ||
872 | return (offset + res); | ||
873 | } | ||
874 | |||
875 | #endif /* __s390x__ */ | 758 | #endif /* __s390x__ */ |
876 | 759 | ||
877 | /* | 760 | static inline int |
878 | * ffz = Find First Zero in word. Undefined if no zero exists, | 761 | find_next_zero_bit (const unsigned long * addr, unsigned long size, |
879 | * so code should check against ~0UL first.. | 762 | unsigned long offset) |
880 | */ | ||
881 | static inline unsigned long ffz(unsigned long word) | ||
882 | { | 763 | { |
883 | unsigned long bit = 0; | 764 | const unsigned long *p; |
884 | 765 | unsigned long bit, set; | |
885 | #ifdef __s390x__ | 766 | |
886 | if (likely((word & 0xffffffff) == 0xffffffff)) { | 767 | if (offset >= size) |
887 | word >>= 32; | 768 | return size; |
888 | bit += 32; | 769 | bit = offset & (__BITOPS_WORDSIZE - 1); |
889 | } | 770 | offset -= bit; |
890 | #endif | 771 | size -= offset; |
891 | if (likely((word & 0xffff) == 0xffff)) { | 772 | p = addr + offset / __BITOPS_WORDSIZE; |
892 | word >>= 16; | 773 | if (bit) { |
893 | bit += 16; | 774 | /* |
775 | * s390 version of ffz returns __BITOPS_WORDSIZE | ||
776 | * if no zero bit is present in the word. | ||
777 | */ | ||
778 | set = ffz(*p >> bit) + bit; | ||
779 | if (set >= size) | ||
780 | return size + offset; | ||
781 | if (set < __BITOPS_WORDSIZE) | ||
782 | return set + offset; | ||
783 | offset += __BITOPS_WORDSIZE; | ||
784 | size -= __BITOPS_WORDSIZE; | ||
785 | p++; | ||
894 | } | 786 | } |
895 | if (likely((word & 0xff) == 0xff)) { | 787 | return offset + find_first_zero_bit(p, size); |
896 | word >>= 8; | ||
897 | bit += 8; | ||
898 | } | ||
899 | return bit + _zb_findmap[word & 0xff]; | ||
900 | } | 788 | } |
901 | 789 | ||
902 | /* | 790 | static inline int |
903 | * __ffs = find first bit in word. Undefined if no bit exists, | 791 | find_next_bit (const unsigned long * addr, unsigned long size, |
904 | * so code should check against 0UL first.. | 792 | unsigned long offset) |
905 | */ | ||
906 | static inline unsigned long __ffs (unsigned long word) | ||
907 | { | 793 | { |
908 | unsigned long bit = 0; | 794 | const unsigned long *p; |
909 | 795 | unsigned long bit, set; | |
910 | #ifdef __s390x__ | 796 | |
911 | if (likely((word & 0xffffffff) == 0)) { | 797 | if (offset >= size) |
912 | word >>= 32; | 798 | return size; |
913 | bit += 32; | 799 | bit = offset & (__BITOPS_WORDSIZE - 1); |
800 | offset -= bit; | ||
801 | size -= offset; | ||
802 | p = addr + offset / __BITOPS_WORDSIZE; | ||
803 | if (bit) { | ||
804 | /* | ||
805 | * s390 version of __ffs returns __BITOPS_WORDSIZE | ||
806 | * if no one bit is present in the word. | ||
807 | */ | ||
808 | set = __ffs(*p & (~0UL << bit)); | ||
809 | if (set >= size) | ||
810 | return size + offset; | ||
811 | if (set < __BITOPS_WORDSIZE) | ||
812 | return set + offset; | ||
813 | offset += __BITOPS_WORDSIZE; | ||
814 | size -= __BITOPS_WORDSIZE; | ||
815 | p++; | ||
914 | } | 816 | } |
915 | #endif | 817 | return offset + find_first_bit(p, size); |
916 | if (likely((word & 0xffff) == 0)) { | ||
917 | word >>= 16; | ||
918 | bit += 16; | ||
919 | } | ||
920 | if (likely((word & 0xff) == 0)) { | ||
921 | word >>= 8; | ||
922 | bit += 8; | ||
923 | } | ||
924 | return bit + _sb_findmap[word & 0xff]; | ||
925 | } | 818 | } |
926 | 819 | ||
927 | /* | 820 | /* |
@@ -1031,49 +924,6 @@ ext2_find_first_zero_bit(void *vaddr, unsigned int size) | |||
1031 | return (res < size) ? res : size; | 924 | return (res < size) ? res : size; |
1032 | } | 925 | } |
1033 | 926 | ||
1034 | static inline int | ||
1035 | ext2_find_next_zero_bit(void *vaddr, unsigned int size, unsigned offset) | ||
1036 | { | ||
1037 | unsigned long *addr = vaddr; | ||
1038 | unsigned long *p = addr + (offset >> 5); | ||
1039 | unsigned long word, reg; | ||
1040 | unsigned int bit = offset & 31UL, res; | ||
1041 | |||
1042 | if (offset >= size) | ||
1043 | return size; | ||
1044 | |||
1045 | if (bit) { | ||
1046 | __asm__(" ic %0,0(%1)\n" | ||
1047 | " icm %0,2,1(%1)\n" | ||
1048 | " icm %0,4,2(%1)\n" | ||
1049 | " icm %0,8,3(%1)" | ||
1050 | : "=&a" (word) : "a" (p) : "cc" ); | ||
1051 | word >>= bit; | ||
1052 | res = bit; | ||
1053 | /* Look for zero in first longword */ | ||
1054 | __asm__(" lhi %2,0xff\n" | ||
1055 | " tml %1,0xffff\n" | ||
1056 | " jno 0f\n" | ||
1057 | " ahi %0,16\n" | ||
1058 | " srl %1,16\n" | ||
1059 | "0: tml %1,0x00ff\n" | ||
1060 | " jno 1f\n" | ||
1061 | " ahi %0,8\n" | ||
1062 | " srl %1,8\n" | ||
1063 | "1: nr %1,%2\n" | ||
1064 | " ic %1,0(%1,%3)\n" | ||
1065 | " alr %0,%1" | ||
1066 | : "+&d" (res), "+&a" (word), "=&d" (reg) | ||
1067 | : "a" (&_zb_findmap) : "cc" ); | ||
1068 | if (res < 32) | ||
1069 | return (p - addr)*32 + res; | ||
1070 | p++; | ||
1071 | } | ||
1072 | /* No zero yet, search remaining full bytes for a zero */ | ||
1073 | res = ext2_find_first_zero_bit (p, size - 32 * (p - addr)); | ||
1074 | return (p - addr) * 32 + res; | ||
1075 | } | ||
1076 | |||
1077 | #else /* __s390x__ */ | 927 | #else /* __s390x__ */ |
1078 | 928 | ||
1079 | static inline unsigned long | 929 | static inline unsigned long |
@@ -1120,56 +970,46 @@ ext2_find_first_zero_bit(void *vaddr, unsigned long size) | |||
1120 | return (res < size) ? res : size; | 970 | return (res < size) ? res : size; |
1121 | } | 971 | } |
1122 | 972 | ||
1123 | static inline unsigned long | 973 | #endif /* __s390x__ */ |
974 | |||
975 | static inline int | ||
1124 | ext2_find_next_zero_bit(void *vaddr, unsigned long size, unsigned long offset) | 976 | ext2_find_next_zero_bit(void *vaddr, unsigned long size, unsigned long offset) |
1125 | { | 977 | { |
1126 | unsigned long *addr = vaddr; | 978 | unsigned long *addr = vaddr, *p; |
1127 | unsigned long *p = addr + (offset >> 6); | 979 | unsigned long word, bit, set; |
1128 | unsigned long word, reg; | ||
1129 | unsigned long bit = offset & 63UL, res; | ||
1130 | 980 | ||
1131 | if (offset >= size) | 981 | if (offset >= size) |
1132 | return size; | 982 | return size; |
1133 | 983 | bit = offset & (__BITOPS_WORDSIZE - 1); | |
984 | offset -= bit; | ||
985 | size -= offset; | ||
986 | p = addr + offset / __BITOPS_WORDSIZE; | ||
1134 | if (bit) { | 987 | if (bit) { |
1135 | __asm__(" lrvg %0,%1" /* load reversed, neat instruction */ | 988 | #ifndef __s390x__ |
1136 | : "=a" (word) : "m" (*p) ); | 989 | asm(" ic %0,0(%1)\n" |
1137 | word >>= bit; | 990 | " icm %0,2,1(%1)\n" |
1138 | res = bit; | 991 | " icm %0,4,2(%1)\n" |
1139 | /* Look for zero in first 8 byte word */ | 992 | " icm %0,8,3(%1)" |
1140 | __asm__(" lghi %2,0xff\n" | 993 | : "=&a" (word) : "a" (p), "m" (*p) : "cc" ); |
1141 | " tmll %1,0xffff\n" | 994 | #else |
1142 | " jno 2f\n" | 995 | asm(" lrvg %0,%1" : "=a" (word) : "m" (*p) ); |
1143 | " ahi %0,16\n" | 996 | #endif |
1144 | " srlg %1,%1,16\n" | 997 | /* |
1145 | "0: tmll %1,0xffff\n" | 998 | * s390 version of ffz returns __BITOPS_WORDSIZE |
1146 | " jno 2f\n" | 999 | * if no zero bit is present in the word. |
1147 | " ahi %0,16\n" | 1000 | */ |
1148 | " srlg %1,%1,16\n" | 1001 | set = ffz(word >> bit) + bit; |
1149 | "1: tmll %1,0xffff\n" | 1002 | if (set >= size) |
1150 | " jno 2f\n" | 1003 | return size + offset; |
1151 | " ahi %0,16\n" | 1004 | if (set < __BITOPS_WORDSIZE) |
1152 | " srl %1,16\n" | 1005 | return set + offset; |
1153 | "2: tmll %1,0x00ff\n" | 1006 | offset += __BITOPS_WORDSIZE; |
1154 | " jno 3f\n" | 1007 | size -= __BITOPS_WORDSIZE; |
1155 | " ahi %0,8\n" | 1008 | p++; |
1156 | " srl %1,8\n" | ||
1157 | "3: ngr %1,%2\n" | ||
1158 | " ic %1,0(%1,%3)\n" | ||
1159 | " alr %0,%1" | ||
1160 | : "+&d" (res), "+a" (word), "=&d" (reg) | ||
1161 | : "a" (&_zb_findmap) : "cc" ); | ||
1162 | if (res < 64) | ||
1163 | return (p - addr)*64 + res; | ||
1164 | p++; | ||
1165 | } | 1009 | } |
1166 | /* No zero yet, search remaining full bytes for a zero */ | 1010 | return offset + ext2_find_first_zero_bit(p, size); |
1167 | res = ext2_find_first_zero_bit (p, size - 64 * (p - addr)); | ||
1168 | return (p - addr) * 64 + res; | ||
1169 | } | 1011 | } |
1170 | 1012 | ||
1171 | #endif /* __s390x__ */ | ||
1172 | |||
1173 | /* Bitmap functions for the minix filesystem. */ | 1013 | /* Bitmap functions for the minix filesystem. */ |
1174 | /* FIXME !!! */ | 1014 | /* FIXME !!! */ |
1175 | #define minix_test_and_set_bit(nr,addr) \ | 1015 | #define minix_test_and_set_bit(nr,addr) \ |
diff --git a/include/asm-s390/cpcmd.h b/include/asm-s390/cpcmd.h index 1d33c5da083e..1fcf65be7a23 100644 --- a/include/asm-s390/cpcmd.h +++ b/include/asm-s390/cpcmd.h | |||
@@ -11,14 +11,28 @@ | |||
11 | #define __CPCMD__ | 11 | #define __CPCMD__ |
12 | 12 | ||
13 | /* | 13 | /* |
14 | * the lowlevel function for cpcmd | ||
14 | * the caller of __cpcmd has to ensure that the response buffer is below 2 GB | 15 | * the caller of __cpcmd has to ensure that the response buffer is below 2 GB |
15 | */ | 16 | */ |
16 | extern void __cpcmd(char *cmd, char *response, int rlen); | 17 | extern int __cpcmd(const char *cmd, char *response, int rlen, int *response_code); |
17 | 18 | ||
18 | #ifndef __s390x__ | 19 | #ifndef __s390x__ |
19 | #define cpcmd __cpcmd | 20 | #define cpcmd __cpcmd |
20 | #else | 21 | #else |
21 | extern void cpcmd(char *cmd, char *response, int rlen); | 22 | /* |
23 | * cpcmd is the in-kernel interface for issuing CP commands | ||
24 | * | ||
25 | * cmd: null-terminated command string, max 240 characters | ||
26 | * response: response buffer for VM's textual response | ||
27 | * rlen: size of the response buffer, cpcmd will not exceed this size | ||
28 | * but will cap the output, if its too large. Everything that | ||
29 | * did not fit into the buffer will be silently dropped | ||
30 | * response_code: return pointer for VM's error code | ||
31 | * return value: the size of the response. The caller can check if the buffer | ||
32 | * was large enough by comparing the return value and rlen | ||
33 | * NOTE: If the response buffer is not below 2 GB, cpcmd can sleep | ||
34 | */ | ||
35 | extern int cpcmd(const char *cmd, char *response, int rlen, int *response_code); | ||
22 | #endif /*__s390x__*/ | 36 | #endif /*__s390x__*/ |
23 | 37 | ||
24 | #endif | 38 | #endif |
diff --git a/include/asm-s390/debug.h b/include/asm-s390/debug.h index 6bbcdea42a86..92360d90144b 100644 --- a/include/asm-s390/debug.h +++ b/include/asm-s390/debug.h | |||
@@ -9,6 +9,8 @@ | |||
9 | #ifndef DEBUG_H | 9 | #ifndef DEBUG_H |
10 | #define DEBUG_H | 10 | #define DEBUG_H |
11 | 11 | ||
12 | #include <linux/config.h> | ||
13 | #include <linux/fs.h> | ||
12 | #include <linux/string.h> | 14 | #include <linux/string.h> |
13 | 15 | ||
14 | /* Note: | 16 | /* Note: |
@@ -31,19 +33,18 @@ struct __debug_entry{ | |||
31 | } __attribute__((packed)); | 33 | } __attribute__((packed)); |
32 | 34 | ||
33 | 35 | ||
34 | #define __DEBUG_FEATURE_VERSION 1 /* version of debug feature */ | 36 | #define __DEBUG_FEATURE_VERSION 2 /* version of debug feature */ |
35 | 37 | ||
36 | #ifdef __KERNEL__ | 38 | #ifdef __KERNEL__ |
37 | #include <linux/spinlock.h> | 39 | #include <linux/spinlock.h> |
38 | #include <linux/kernel.h> | 40 | #include <linux/kernel.h> |
39 | #include <linux/time.h> | 41 | #include <linux/time.h> |
40 | #include <linux/proc_fs.h> | ||
41 | 42 | ||
42 | #define DEBUG_MAX_LEVEL 6 /* debug levels range from 0 to 6 */ | 43 | #define DEBUG_MAX_LEVEL 6 /* debug levels range from 0 to 6 */ |
43 | #define DEBUG_OFF_LEVEL -1 /* level where debug is switched off */ | 44 | #define DEBUG_OFF_LEVEL -1 /* level where debug is switched off */ |
44 | #define DEBUG_FLUSH_ALL -1 /* parameter to flush all areas */ | 45 | #define DEBUG_FLUSH_ALL -1 /* parameter to flush all areas */ |
45 | #define DEBUG_MAX_VIEWS 10 /* max number of views in proc fs */ | 46 | #define DEBUG_MAX_VIEWS 10 /* max number of views in proc fs */ |
46 | #define DEBUG_MAX_PROCF_LEN 64 /* max length for a proc file name */ | 47 | #define DEBUG_MAX_NAME_LEN 64 /* max length for a debugfs file name */ |
47 | #define DEBUG_DEFAULT_LEVEL 3 /* initial debug level */ | 48 | #define DEBUG_DEFAULT_LEVEL 3 /* initial debug level */ |
48 | 49 | ||
49 | #define DEBUG_DIR_ROOT "s390dbf" /* name of debug root directory in proc fs */ | 50 | #define DEBUG_DIR_ROOT "s390dbf" /* name of debug root directory in proc fs */ |
@@ -64,16 +65,17 @@ typedef struct debug_info { | |||
64 | spinlock_t lock; | 65 | spinlock_t lock; |
65 | int level; | 66 | int level; |
66 | int nr_areas; | 67 | int nr_areas; |
67 | int page_order; | 68 | int pages_per_area; |
68 | int buf_size; | 69 | int buf_size; |
69 | int entry_size; | 70 | int entry_size; |
70 | debug_entry_t** areas; | 71 | debug_entry_t*** areas; |
71 | int active_area; | 72 | int active_area; |
72 | int *active_entry; | 73 | int *active_pages; |
73 | struct proc_dir_entry* proc_root_entry; | 74 | int *active_entries; |
74 | struct proc_dir_entry* proc_entries[DEBUG_MAX_VIEWS]; | 75 | struct dentry* debugfs_root_entry; |
76 | struct dentry* debugfs_entries[DEBUG_MAX_VIEWS]; | ||
75 | struct debug_view* views[DEBUG_MAX_VIEWS]; | 77 | struct debug_view* views[DEBUG_MAX_VIEWS]; |
76 | char name[DEBUG_MAX_PROCF_LEN]; | 78 | char name[DEBUG_MAX_NAME_LEN]; |
77 | } debug_info_t; | 79 | } debug_info_t; |
78 | 80 | ||
79 | typedef int (debug_header_proc_t) (debug_info_t* id, | 81 | typedef int (debug_header_proc_t) (debug_info_t* id, |
@@ -98,7 +100,7 @@ int debug_dflt_header_fn(debug_info_t* id, struct debug_view* view, | |||
98 | int area, debug_entry_t* entry, char* out_buf); | 100 | int area, debug_entry_t* entry, char* out_buf); |
99 | 101 | ||
100 | struct debug_view { | 102 | struct debug_view { |
101 | char name[DEBUG_MAX_PROCF_LEN]; | 103 | char name[DEBUG_MAX_NAME_LEN]; |
102 | debug_prolog_proc_t* prolog_proc; | 104 | debug_prolog_proc_t* prolog_proc; |
103 | debug_header_proc_t* header_proc; | 105 | debug_header_proc_t* header_proc; |
104 | debug_format_proc_t* format_proc; | 106 | debug_format_proc_t* format_proc; |
@@ -120,7 +122,7 @@ debug_entry_t* debug_exception_common(debug_info_t* id, int level, | |||
120 | 122 | ||
121 | /* Debug Feature API: */ | 123 | /* Debug Feature API: */ |
122 | 124 | ||
123 | debug_info_t* debug_register(char* name, int pages_index, int nr_areas, | 125 | debug_info_t* debug_register(char* name, int pages, int nr_areas, |
124 | int buf_size); | 126 | int buf_size); |
125 | 127 | ||
126 | void debug_unregister(debug_info_t* id); | 128 | void debug_unregister(debug_info_t* id); |
@@ -132,7 +134,8 @@ void debug_stop_all(void); | |||
132 | extern inline debug_entry_t* | 134 | extern inline debug_entry_t* |
133 | debug_event(debug_info_t* id, int level, void* data, int length) | 135 | debug_event(debug_info_t* id, int level, void* data, int length) |
134 | { | 136 | { |
135 | if ((!id) || (level > id->level)) return NULL; | 137 | if ((!id) || (level > id->level) || (id->pages_per_area == 0)) |
138 | return NULL; | ||
136 | return debug_event_common(id,level,data,length); | 139 | return debug_event_common(id,level,data,length); |
137 | } | 140 | } |
138 | 141 | ||
@@ -140,7 +143,8 @@ extern inline debug_entry_t* | |||
140 | debug_int_event(debug_info_t* id, int level, unsigned int tag) | 143 | debug_int_event(debug_info_t* id, int level, unsigned int tag) |
141 | { | 144 | { |
142 | unsigned int t=tag; | 145 | unsigned int t=tag; |
143 | if ((!id) || (level > id->level)) return NULL; | 146 | if ((!id) || (level > id->level) || (id->pages_per_area == 0)) |
147 | return NULL; | ||
144 | return debug_event_common(id,level,&t,sizeof(unsigned int)); | 148 | return debug_event_common(id,level,&t,sizeof(unsigned int)); |
145 | } | 149 | } |
146 | 150 | ||
@@ -148,14 +152,16 @@ extern inline debug_entry_t * | |||
148 | debug_long_event (debug_info_t* id, int level, unsigned long tag) | 152 | debug_long_event (debug_info_t* id, int level, unsigned long tag) |
149 | { | 153 | { |
150 | unsigned long t=tag; | 154 | unsigned long t=tag; |
151 | if ((!id) || (level > id->level)) return NULL; | 155 | if ((!id) || (level > id->level) || (id->pages_per_area == 0)) |
156 | return NULL; | ||
152 | return debug_event_common(id,level,&t,sizeof(unsigned long)); | 157 | return debug_event_common(id,level,&t,sizeof(unsigned long)); |
153 | } | 158 | } |
154 | 159 | ||
155 | extern inline debug_entry_t* | 160 | extern inline debug_entry_t* |
156 | debug_text_event(debug_info_t* id, int level, const char* txt) | 161 | debug_text_event(debug_info_t* id, int level, const char* txt) |
157 | { | 162 | { |
158 | if ((!id) || (level > id->level)) return NULL; | 163 | if ((!id) || (level > id->level) || (id->pages_per_area == 0)) |
164 | return NULL; | ||
159 | return debug_event_common(id,level,txt,strlen(txt)); | 165 | return debug_event_common(id,level,txt,strlen(txt)); |
160 | } | 166 | } |
161 | 167 | ||
@@ -167,7 +173,8 @@ debug_sprintf_event(debug_info_t* id,int level,char *string,...) | |||
167 | extern inline debug_entry_t* | 173 | extern inline debug_entry_t* |
168 | debug_exception(debug_info_t* id, int level, void* data, int length) | 174 | debug_exception(debug_info_t* id, int level, void* data, int length) |
169 | { | 175 | { |
170 | if ((!id) || (level > id->level)) return NULL; | 176 | if ((!id) || (level > id->level) || (id->pages_per_area == 0)) |
177 | return NULL; | ||
171 | return debug_exception_common(id,level,data,length); | 178 | return debug_exception_common(id,level,data,length); |
172 | } | 179 | } |
173 | 180 | ||
@@ -175,7 +182,8 @@ extern inline debug_entry_t* | |||
175 | debug_int_exception(debug_info_t* id, int level, unsigned int tag) | 182 | debug_int_exception(debug_info_t* id, int level, unsigned int tag) |
176 | { | 183 | { |
177 | unsigned int t=tag; | 184 | unsigned int t=tag; |
178 | if ((!id) || (level > id->level)) return NULL; | 185 | if ((!id) || (level > id->level) || (id->pages_per_area == 0)) |
186 | return NULL; | ||
179 | return debug_exception_common(id,level,&t,sizeof(unsigned int)); | 187 | return debug_exception_common(id,level,&t,sizeof(unsigned int)); |
180 | } | 188 | } |
181 | 189 | ||
@@ -183,14 +191,16 @@ extern inline debug_entry_t * | |||
183 | debug_long_exception (debug_info_t* id, int level, unsigned long tag) | 191 | debug_long_exception (debug_info_t* id, int level, unsigned long tag) |
184 | { | 192 | { |
185 | unsigned long t=tag; | 193 | unsigned long t=tag; |
186 | if ((!id) || (level > id->level)) return NULL; | 194 | if ((!id) || (level > id->level) || (id->pages_per_area == 0)) |
195 | return NULL; | ||
187 | return debug_exception_common(id,level,&t,sizeof(unsigned long)); | 196 | return debug_exception_common(id,level,&t,sizeof(unsigned long)); |
188 | } | 197 | } |
189 | 198 | ||
190 | extern inline debug_entry_t* | 199 | extern inline debug_entry_t* |
191 | debug_text_exception(debug_info_t* id, int level, const char* txt) | 200 | debug_text_exception(debug_info_t* id, int level, const char* txt) |
192 | { | 201 | { |
193 | if ((!id) || (level > id->level)) return NULL; | 202 | if ((!id) || (level > id->level) || (id->pages_per_area == 0)) |
203 | return NULL; | ||
194 | return debug_exception_common(id,level,txt,strlen(txt)); | 204 | return debug_exception_common(id,level,txt,strlen(txt)); |
195 | } | 205 | } |
196 | 206 | ||
diff --git a/include/asm-s390/emergency-restart.h b/include/asm-s390/emergency-restart.h new file mode 100644 index 000000000000..108d8c48e42e --- /dev/null +++ b/include/asm-s390/emergency-restart.h | |||
@@ -0,0 +1,6 @@ | |||
1 | #ifndef _ASM_EMERGENCY_RESTART_H | ||
2 | #define _ASM_EMERGENCY_RESTART_H | ||
3 | |||
4 | #include <asm-generic/emergency-restart.h> | ||
5 | |||
6 | #endif /* _ASM_EMERGENCY_RESTART_H */ | ||
diff --git a/include/asm-s390/kexec.h b/include/asm-s390/kexec.h new file mode 100644 index 000000000000..54cf7d9f251c --- /dev/null +++ b/include/asm-s390/kexec.h | |||
@@ -0,0 +1,42 @@ | |||
1 | /* | ||
2 | * include/asm-s390/kexec.h | ||
3 | * | ||
4 | * (C) Copyright IBM Corp. 2005 | ||
5 | * | ||
6 | * Author(s): Rolf Adelsberger <adelsberger@de.ibm.com> | ||
7 | * | ||
8 | */ | ||
9 | |||
10 | #ifndef _S390_KEXEC_H | ||
11 | #define _S390_KEXEC_H | ||
12 | |||
13 | #include <asm/page.h> | ||
14 | #include <asm/processor.h> | ||
15 | /* | ||
16 | * KEXEC_SOURCE_MEMORY_LIMIT maximum page get_free_page can return. | ||
17 | * I.e. Maximum page that is mapped directly into kernel memory, | ||
18 | * and kmap is not required. | ||
19 | */ | ||
20 | |||
21 | /* Maximum physical address we can use pages from */ | ||
22 | #define KEXEC_SOURCE_MEMORY_LIMIT (-1UL) | ||
23 | |||
24 | /* Maximum address we can reach in physical address mode */ | ||
25 | #define KEXEC_DESTINATION_MEMORY_LIMIT (-1UL) | ||
26 | |||
27 | /* Maximum address we can use for the control pages */ | ||
28 | /* Not more than 2GB */ | ||
29 | #define KEXEC_CONTROL_MEMORY_LIMIT (1<<31) | ||
30 | |||
31 | /* Allocate one page for the pdp and the second for the code */ | ||
32 | #define KEXEC_CONTROL_CODE_SIZE 4096 | ||
33 | |||
34 | /* The native architecture */ | ||
35 | #define KEXEC_ARCH KEXEC_ARCH_S390 | ||
36 | |||
37 | #define MAX_NOTE_BYTES 1024 | ||
38 | typedef u32 note_buf_t[MAX_NOTE_BYTES/4]; | ||
39 | |||
40 | extern note_buf_t crash_notes[]; | ||
41 | |||
42 | #endif /*_S390_KEXEC_H */ | ||
diff --git a/include/asm-s390/lowcore.h b/include/asm-s390/lowcore.h index df5172fc589d..afe6a9f9b0ae 100644 --- a/include/asm-s390/lowcore.h +++ b/include/asm-s390/lowcore.h | |||
@@ -90,7 +90,6 @@ | |||
90 | #define __LC_SYSTEM_TIMER 0x278 | 90 | #define __LC_SYSTEM_TIMER 0x278 |
91 | #define __LC_LAST_UPDATE_CLOCK 0x280 | 91 | #define __LC_LAST_UPDATE_CLOCK 0x280 |
92 | #define __LC_STEAL_CLOCK 0x288 | 92 | #define __LC_STEAL_CLOCK 0x288 |
93 | #define __LC_DIAG44_OPCODE 0x290 | ||
94 | #define __LC_KERNEL_STACK 0xD40 | 93 | #define __LC_KERNEL_STACK 0xD40 |
95 | #define __LC_THREAD_INFO 0xD48 | 94 | #define __LC_THREAD_INFO 0xD48 |
96 | #define __LC_ASYNC_STACK 0xD50 | 95 | #define __LC_ASYNC_STACK 0xD50 |
@@ -109,10 +108,14 @@ | |||
109 | 108 | ||
110 | #ifndef __s390x__ | 109 | #ifndef __s390x__ |
111 | #define __LC_PFAULT_INTPARM 0x080 | 110 | #define __LC_PFAULT_INTPARM 0x080 |
111 | #define __LC_CPU_TIMER_SAVE_AREA 0x0D8 | ||
112 | #define __LC_AREGS_SAVE_AREA 0x120 | 112 | #define __LC_AREGS_SAVE_AREA 0x120 |
113 | #define __LC_GPREGS_SAVE_AREA 0x180 | ||
113 | #define __LC_CREGS_SAVE_AREA 0x1C0 | 114 | #define __LC_CREGS_SAVE_AREA 0x1C0 |
114 | #else /* __s390x__ */ | 115 | #else /* __s390x__ */ |
115 | #define __LC_PFAULT_INTPARM 0x11B8 | 116 | #define __LC_PFAULT_INTPARM 0x11B8 |
117 | #define __LC_GPREGS_SAVE_AREA 0x1280 | ||
118 | #define __LC_CPU_TIMER_SAVE_AREA 0x1328 | ||
116 | #define __LC_AREGS_SAVE_AREA 0x1340 | 119 | #define __LC_AREGS_SAVE_AREA 0x1340 |
117 | #define __LC_CREGS_SAVE_AREA 0x1380 | 120 | #define __LC_CREGS_SAVE_AREA 0x1380 |
118 | #endif /* __s390x__ */ | 121 | #endif /* __s390x__ */ |
@@ -167,7 +170,8 @@ struct _lowcore | |||
167 | __u16 subchannel_nr; /* 0x0ba */ | 170 | __u16 subchannel_nr; /* 0x0ba */ |
168 | __u32 io_int_parm; /* 0x0bc */ | 171 | __u32 io_int_parm; /* 0x0bc */ |
169 | __u32 io_int_word; /* 0x0c0 */ | 172 | __u32 io_int_word; /* 0x0c0 */ |
170 | __u8 pad3[0xD8-0xC4]; /* 0x0c4 */ | 173 | __u8 pad3[0xD4-0xC4]; /* 0x0c4 */ |
174 | __u32 extended_save_area_addr; /* 0x0d4 */ | ||
171 | __u32 cpu_timer_save_area[2]; /* 0x0d8 */ | 175 | __u32 cpu_timer_save_area[2]; /* 0x0d8 */ |
172 | __u32 clock_comp_save_area[2]; /* 0x0e0 */ | 176 | __u32 clock_comp_save_area[2]; /* 0x0e0 */ |
173 | __u32 mcck_interruption_code[2]; /* 0x0e8 */ | 177 | __u32 mcck_interruption_code[2]; /* 0x0e8 */ |
@@ -281,8 +285,7 @@ struct _lowcore | |||
281 | __u64 system_timer; /* 0x278 */ | 285 | __u64 system_timer; /* 0x278 */ |
282 | __u64 last_update_clock; /* 0x280 */ | 286 | __u64 last_update_clock; /* 0x280 */ |
283 | __u64 steal_clock; /* 0x288 */ | 287 | __u64 steal_clock; /* 0x288 */ |
284 | __u32 diag44_opcode; /* 0x290 */ | 288 | __u8 pad8[0xc00-0x290]; /* 0x290 */ |
285 | __u8 pad8[0xc00-0x294]; /* 0x294 */ | ||
286 | /* System info area */ | 289 | /* System info area */ |
287 | __u64 save_area[16]; /* 0xc00 */ | 290 | __u64 save_area[16]; /* 0xc00 */ |
288 | __u8 pad9[0xd40-0xc80]; /* 0xc80 */ | 291 | __u8 pad9[0xd40-0xc80]; /* 0xc80 */ |
diff --git a/include/asm-s390/processor.h b/include/asm-s390/processor.h index fb46e9090b50..4ec652ebb3b1 100644 --- a/include/asm-s390/processor.h +++ b/include/asm-s390/processor.h | |||
@@ -203,10 +203,25 @@ unsigned long get_wchan(struct task_struct *p); | |||
203 | # define cpu_relax() asm volatile ("diag 0,0,68" : : : "memory") | 203 | # define cpu_relax() asm volatile ("diag 0,0,68" : : : "memory") |
204 | #else /* __s390x__ */ | 204 | #else /* __s390x__ */ |
205 | # define cpu_relax() \ | 205 | # define cpu_relax() \ |
206 | asm volatile ("ex 0,%0" : : "i" (__LC_DIAG44_OPCODE) : "memory") | 206 | do { \ |
207 | if (MACHINE_HAS_DIAG44) \ | ||
208 | asm volatile ("diag 0,0,68" : : : "memory"); \ | ||
209 | } while (0) | ||
207 | #endif /* __s390x__ */ | 210 | #endif /* __s390x__ */ |
208 | 211 | ||
209 | /* | 212 | /* |
213 | * Set PSW to specified value. | ||
214 | */ | ||
215 | static inline void __load_psw(psw_t psw) | ||
216 | { | ||
217 | #ifndef __s390x__ | ||
218 | asm volatile ("lpsw 0(%0)" : : "a" (&psw), "m" (psw) : "cc" ); | ||
219 | #else | ||
220 | asm volatile ("lpswe 0(%0)" : : "a" (&psw), "m" (psw) : "cc" ); | ||
221 | #endif | ||
222 | } | ||
223 | |||
224 | /* | ||
210 | * Set PSW mask to specified value, while leaving the | 225 | * Set PSW mask to specified value, while leaving the |
211 | * PSW addr pointing to the next instruction. | 226 | * PSW addr pointing to the next instruction. |
212 | */ | 227 | */ |
@@ -214,8 +229,8 @@ unsigned long get_wchan(struct task_struct *p); | |||
214 | static inline void __load_psw_mask (unsigned long mask) | 229 | static inline void __load_psw_mask (unsigned long mask) |
215 | { | 230 | { |
216 | unsigned long addr; | 231 | unsigned long addr; |
217 | |||
218 | psw_t psw; | 232 | psw_t psw; |
233 | |||
219 | psw.mask = mask; | 234 | psw.mask = mask; |
220 | 235 | ||
221 | #ifndef __s390x__ | 236 | #ifndef __s390x__ |
@@ -241,30 +256,8 @@ static inline void __load_psw_mask (unsigned long mask) | |||
241 | */ | 256 | */ |
242 | static inline void enabled_wait(void) | 257 | static inline void enabled_wait(void) |
243 | { | 258 | { |
244 | unsigned long reg; | 259 | __load_psw_mask(PSW_BASE_BITS | PSW_MASK_IO | PSW_MASK_EXT | |
245 | psw_t wait_psw; | 260 | PSW_MASK_MCHECK | PSW_MASK_WAIT | PSW_DEFAULT_KEY); |
246 | |||
247 | wait_psw.mask = PSW_BASE_BITS | PSW_MASK_IO | PSW_MASK_EXT | | ||
248 | PSW_MASK_MCHECK | PSW_MASK_WAIT | PSW_DEFAULT_KEY; | ||
249 | #ifndef __s390x__ | ||
250 | asm volatile ( | ||
251 | " basr %0,0\n" | ||
252 | "0: la %0,1f-0b(%0)\n" | ||
253 | " st %0,4(%1)\n" | ||
254 | " oi 4(%1),0x80\n" | ||
255 | " lpsw 0(%1)\n" | ||
256 | "1:" | ||
257 | : "=&a" (reg) : "a" (&wait_psw), "m" (wait_psw) | ||
258 | : "memory", "cc" ); | ||
259 | #else /* __s390x__ */ | ||
260 | asm volatile ( | ||
261 | " larl %0,0f\n" | ||
262 | " stg %0,8(%1)\n" | ||
263 | " lpswe 0(%1)\n" | ||
264 | "0:" | ||
265 | : "=&a" (reg) : "a" (&wait_psw), "m" (wait_psw) | ||
266 | : "memory", "cc" ); | ||
267 | #endif /* __s390x__ */ | ||
268 | } | 261 | } |
269 | 262 | ||
270 | /* | 263 | /* |
@@ -273,13 +266,11 @@ static inline void enabled_wait(void) | |||
273 | 266 | ||
274 | static inline void disabled_wait(unsigned long code) | 267 | static inline void disabled_wait(unsigned long code) |
275 | { | 268 | { |
276 | char psw_buffer[2*sizeof(psw_t)]; | ||
277 | unsigned long ctl_buf; | 269 | unsigned long ctl_buf; |
278 | psw_t *dw_psw = (psw_t *)(((unsigned long) &psw_buffer+sizeof(psw_t)-1) | 270 | psw_t dw_psw; |
279 | & -sizeof(psw_t)); | ||
280 | 271 | ||
281 | dw_psw->mask = PSW_BASE_BITS | PSW_MASK_WAIT; | 272 | dw_psw.mask = PSW_BASE_BITS | PSW_MASK_WAIT; |
282 | dw_psw->addr = code; | 273 | dw_psw.addr = code; |
283 | /* | 274 | /* |
284 | * Store status and then load disabled wait psw, | 275 | * Store status and then load disabled wait psw, |
285 | * the processor is dead afterwards | 276 | * the processor is dead afterwards |
@@ -301,7 +292,7 @@ static inline void disabled_wait(unsigned long code) | |||
301 | " oi 0x1c0,0x10\n" /* fake protection bit */ | 292 | " oi 0x1c0,0x10\n" /* fake protection bit */ |
302 | " lpsw 0(%1)" | 293 | " lpsw 0(%1)" |
303 | : "=m" (ctl_buf) | 294 | : "=m" (ctl_buf) |
304 | : "a" (dw_psw), "a" (&ctl_buf), "m" (dw_psw) : "cc" ); | 295 | : "a" (&dw_psw), "a" (&ctl_buf), "m" (dw_psw) : "cc" ); |
305 | #else /* __s390x__ */ | 296 | #else /* __s390x__ */ |
306 | asm volatile (" stctg 0,0,0(%2)\n" | 297 | asm volatile (" stctg 0,0,0(%2)\n" |
307 | " ni 4(%2),0xef\n" /* switch off protection */ | 298 | " ni 4(%2),0xef\n" /* switch off protection */ |
@@ -333,7 +324,7 @@ static inline void disabled_wait(unsigned long code) | |||
333 | " oi 0x384(1),0x10\n" /* fake protection bit */ | 324 | " oi 0x384(1),0x10\n" /* fake protection bit */ |
334 | " lpswe 0(%1)" | 325 | " lpswe 0(%1)" |
335 | : "=m" (ctl_buf) | 326 | : "=m" (ctl_buf) |
336 | : "a" (dw_psw), "a" (&ctl_buf), | 327 | : "a" (&dw_psw), "a" (&ctl_buf), |
337 | "m" (dw_psw) : "cc", "0", "1"); | 328 | "m" (dw_psw) : "cc", "0", "1"); |
338 | #endif /* __s390x__ */ | 329 | #endif /* __s390x__ */ |
339 | } | 330 | } |
diff --git a/include/asm-s390/ptrace.h b/include/asm-s390/ptrace.h index 4eff8f2e3bf1..fc7c96edc697 100644 --- a/include/asm-s390/ptrace.h +++ b/include/asm-s390/ptrace.h | |||
@@ -276,7 +276,7 @@ typedef struct | |||
276 | #endif /* __s390x__ */ | 276 | #endif /* __s390x__ */ |
277 | 277 | ||
278 | #define PSW_KERNEL_BITS (PSW_BASE_BITS | PSW_MASK_DAT | PSW_ASC_PRIMARY | \ | 278 | #define PSW_KERNEL_BITS (PSW_BASE_BITS | PSW_MASK_DAT | PSW_ASC_PRIMARY | \ |
279 | PSW_DEFAULT_KEY) | 279 | PSW_MASK_MCHECK | PSW_DEFAULT_KEY) |
280 | #define PSW_USER_BITS (PSW_BASE_BITS | PSW_MASK_DAT | PSW_ASC_HOME | \ | 280 | #define PSW_USER_BITS (PSW_BASE_BITS | PSW_MASK_DAT | PSW_ASC_HOME | \ |
281 | PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK | \ | 281 | PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK | \ |
282 | PSW_MASK_PSTATE | PSW_DEFAULT_KEY) | 282 | PSW_MASK_PSTATE | PSW_DEFAULT_KEY) |
diff --git a/include/asm-s390/spinlock.h b/include/asm-s390/spinlock.h index 53cc736b9820..8ff10300f7ee 100644 --- a/include/asm-s390/spinlock.h +++ b/include/asm-s390/spinlock.h | |||
@@ -11,21 +11,16 @@ | |||
11 | #ifndef __ASM_SPINLOCK_H | 11 | #ifndef __ASM_SPINLOCK_H |
12 | #define __ASM_SPINLOCK_H | 12 | #define __ASM_SPINLOCK_H |
13 | 13 | ||
14 | #ifdef __s390x__ | 14 | static inline int |
15 | /* | 15 | _raw_compare_and_swap(volatile unsigned int *lock, |
16 | * Grmph, take care of %&#! user space programs that include | 16 | unsigned int old, unsigned int new) |
17 | * asm/spinlock.h. The diagnose is only available in kernel | 17 | { |
18 | * context. | 18 | asm volatile ("cs %0,%3,0(%4)" |
19 | */ | 19 | : "=d" (old), "=m" (*lock) |
20 | #ifdef __KERNEL__ | 20 | : "0" (old), "d" (new), "a" (lock), "m" (*lock) |
21 | #include <asm/lowcore.h> | 21 | : "cc", "memory" ); |
22 | #define __DIAG44_INSN "ex" | 22 | return old; |
23 | #define __DIAG44_OPERAND __LC_DIAG44_OPCODE | 23 | } |
24 | #else | ||
25 | #define __DIAG44_INSN "#" | ||
26 | #define __DIAG44_OPERAND 0 | ||
27 | #endif | ||
28 | #endif /* __s390x__ */ | ||
29 | 24 | ||
30 | /* | 25 | /* |
31 | * Simple spin lock operations. There are two variants, one clears IRQ's | 26 | * Simple spin lock operations. There are two variants, one clears IRQ's |
@@ -41,58 +36,35 @@ typedef struct { | |||
41 | #endif | 36 | #endif |
42 | } __attribute__ ((aligned (4))) spinlock_t; | 37 | } __attribute__ ((aligned (4))) spinlock_t; |
43 | 38 | ||
44 | #define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 } | 39 | #define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 } |
45 | #define spin_lock_init(lp) do { (lp)->lock = 0; } while(0) | 40 | #define spin_lock_init(lp) do { (lp)->lock = 0; } while(0) |
46 | #define spin_unlock_wait(lp) do { barrier(); } while(((volatile spinlock_t *)(lp))->lock) | 41 | #define spin_unlock_wait(lp) do { barrier(); } while(((volatile spinlock_t *)(lp))->lock) |
47 | #define spin_is_locked(x) ((x)->lock != 0) | 42 | #define spin_is_locked(x) ((x)->lock != 0) |
48 | #define _raw_spin_lock_flags(lock, flags) _raw_spin_lock(lock) | 43 | #define _raw_spin_lock_flags(lock, flags) _raw_spin_lock(lock) |
49 | 44 | ||
50 | extern inline void _raw_spin_lock(spinlock_t *lp) | 45 | extern void _raw_spin_lock_wait(spinlock_t *lp, unsigned int pc); |
46 | extern int _raw_spin_trylock_retry(spinlock_t *lp, unsigned int pc); | ||
47 | |||
48 | static inline void _raw_spin_lock(spinlock_t *lp) | ||
51 | { | 49 | { |
52 | #ifndef __s390x__ | 50 | unsigned long pc = (unsigned long) __builtin_return_address(0); |
53 | unsigned int reg1, reg2; | 51 | |
54 | __asm__ __volatile__(" bras %0,1f\n" | 52 | if (unlikely(_raw_compare_and_swap(&lp->lock, 0, pc) != 0)) |
55 | "0: diag 0,0,68\n" | 53 | _raw_spin_lock_wait(lp, pc); |
56 | "1: slr %1,%1\n" | ||
57 | " cs %1,%0,0(%3)\n" | ||
58 | " jl 0b\n" | ||
59 | : "=&d" (reg1), "=&d" (reg2), "=m" (lp->lock) | ||
60 | : "a" (&lp->lock), "m" (lp->lock) | ||
61 | : "cc", "memory" ); | ||
62 | #else /* __s390x__ */ | ||
63 | unsigned long reg1, reg2; | ||
64 | __asm__ __volatile__(" bras %1,1f\n" | ||
65 | "0: " __DIAG44_INSN " 0,%4\n" | ||
66 | "1: slr %0,%0\n" | ||
67 | " cs %0,%1,0(%3)\n" | ||
68 | " jl 0b\n" | ||
69 | : "=&d" (reg1), "=&d" (reg2), "=m" (lp->lock) | ||
70 | : "a" (&lp->lock), "i" (__DIAG44_OPERAND), | ||
71 | "m" (lp->lock) : "cc", "memory" ); | ||
72 | #endif /* __s390x__ */ | ||
73 | } | 54 | } |
74 | 55 | ||
75 | extern inline int _raw_spin_trylock(spinlock_t *lp) | 56 | static inline int _raw_spin_trylock(spinlock_t *lp) |
76 | { | 57 | { |
77 | unsigned long reg; | 58 | unsigned long pc = (unsigned long) __builtin_return_address(0); |
78 | unsigned int result; | 59 | |
79 | 60 | if (likely(_raw_compare_and_swap(&lp->lock, 0, pc) == 0)) | |
80 | __asm__ __volatile__(" basr %1,0\n" | 61 | return 1; |
81 | "0: cs %0,%1,0(%3)" | 62 | return _raw_spin_trylock_retry(lp, pc); |
82 | : "=d" (result), "=&d" (reg), "=m" (lp->lock) | ||
83 | : "a" (&lp->lock), "m" (lp->lock), "0" (0) | ||
84 | : "cc", "memory" ); | ||
85 | return !result; | ||
86 | } | 63 | } |
87 | 64 | ||
88 | extern inline void _raw_spin_unlock(spinlock_t *lp) | 65 | static inline void _raw_spin_unlock(spinlock_t *lp) |
89 | { | 66 | { |
90 | unsigned int old; | 67 | _raw_compare_and_swap(&lp->lock, lp->lock, 0); |
91 | |||
92 | __asm__ __volatile__("cs %0,%3,0(%4)" | ||
93 | : "=d" (old), "=m" (lp->lock) | ||
94 | : "0" (lp->lock), "d" (0), "a" (lp) | ||
95 | : "cc", "memory" ); | ||
96 | } | 68 | } |
97 | 69 | ||
98 | /* | 70 | /* |
@@ -106,7 +78,7 @@ extern inline void _raw_spin_unlock(spinlock_t *lp) | |||
106 | * read-locks. | 78 | * read-locks. |
107 | */ | 79 | */ |
108 | typedef struct { | 80 | typedef struct { |
109 | volatile unsigned long lock; | 81 | volatile unsigned int lock; |
110 | volatile unsigned long owner_pc; | 82 | volatile unsigned long owner_pc; |
111 | #ifdef CONFIG_PREEMPT | 83 | #ifdef CONFIG_PREEMPT |
112 | unsigned int break_lock; | 84 | unsigned int break_lock; |
@@ -129,123 +101,55 @@ typedef struct { | |||
129 | */ | 101 | */ |
130 | #define write_can_lock(x) ((x)->lock == 0) | 102 | #define write_can_lock(x) ((x)->lock == 0) |
131 | 103 | ||
132 | #ifndef __s390x__ | 104 | extern void _raw_read_lock_wait(rwlock_t *lp); |
133 | #define _raw_read_lock(rw) \ | 105 | extern int _raw_read_trylock_retry(rwlock_t *lp); |
134 | asm volatile(" l 2,0(%1)\n" \ | 106 | extern void _raw_write_lock_wait(rwlock_t *lp); |
135 | " j 1f\n" \ | 107 | extern int _raw_write_trylock_retry(rwlock_t *lp); |
136 | "0: diag 0,0,68\n" \ | 108 | |
137 | "1: la 2,0(2)\n" /* clear high (=write) bit */ \ | 109 | static inline void _raw_read_lock(rwlock_t *rw) |
138 | " la 3,1(2)\n" /* one more reader */ \ | 110 | { |
139 | " cs 2,3,0(%1)\n" /* try to write new value */ \ | 111 | unsigned int old; |
140 | " jl 0b" \ | 112 | old = rw->lock & 0x7fffffffU; |
141 | : "=m" ((rw)->lock) : "a" (&(rw)->lock), \ | 113 | if (_raw_compare_and_swap(&rw->lock, old, old + 1) != old) |
142 | "m" ((rw)->lock) : "2", "3", "cc", "memory" ) | 114 | _raw_read_lock_wait(rw); |
143 | #else /* __s390x__ */ | 115 | } |
144 | #define _raw_read_lock(rw) \ | 116 | |
145 | asm volatile(" lg 2,0(%1)\n" \ | 117 | static inline void _raw_read_unlock(rwlock_t *rw) |
146 | " j 1f\n" \ | 118 | { |
147 | "0: " __DIAG44_INSN " 0,%2\n" \ | 119 | unsigned int old, cmp; |
148 | "1: nihh 2,0x7fff\n" /* clear high (=write) bit */ \ | 120 | |
149 | " la 3,1(2)\n" /* one more reader */ \ | 121 | old = rw->lock; |
150 | " csg 2,3,0(%1)\n" /* try to write new value */ \ | 122 | do { |
151 | " jl 0b" \ | 123 | cmp = old; |
152 | : "=m" ((rw)->lock) \ | 124 | old = _raw_compare_and_swap(&rw->lock, old, old - 1); |
153 | : "a" (&(rw)->lock), "i" (__DIAG44_OPERAND), \ | 125 | } while (cmp != old); |
154 | "m" ((rw)->lock) : "2", "3", "cc", "memory" ) | 126 | } |
155 | #endif /* __s390x__ */ | 127 | |
156 | 128 | static inline void _raw_write_lock(rwlock_t *rw) | |
157 | #ifndef __s390x__ | 129 | { |
158 | #define _raw_read_unlock(rw) \ | 130 | if (unlikely(_raw_compare_and_swap(&rw->lock, 0, 0x80000000) != 0)) |
159 | asm volatile(" l 2,0(%1)\n" \ | 131 | _raw_write_lock_wait(rw); |
160 | " j 1f\n" \ | 132 | } |
161 | "0: diag 0,0,68\n" \ | 133 | |
162 | "1: lr 3,2\n" \ | 134 | static inline void _raw_write_unlock(rwlock_t *rw) |
163 | " ahi 3,-1\n" /* one less reader */ \ | 135 | { |
164 | " cs 2,3,0(%1)\n" \ | 136 | _raw_compare_and_swap(&rw->lock, 0x80000000, 0); |
165 | " jl 0b" \ | 137 | } |
166 | : "=m" ((rw)->lock) : "a" (&(rw)->lock), \ | 138 | |
167 | "m" ((rw)->lock) : "2", "3", "cc", "memory" ) | 139 | static inline int _raw_read_trylock(rwlock_t *rw) |
168 | #else /* __s390x__ */ | 140 | { |
169 | #define _raw_read_unlock(rw) \ | 141 | unsigned int old; |
170 | asm volatile(" lg 2,0(%1)\n" \ | 142 | old = rw->lock & 0x7fffffffU; |
171 | " j 1f\n" \ | 143 | if (likely(_raw_compare_and_swap(&rw->lock, old, old + 1) == old)) |
172 | "0: " __DIAG44_INSN " 0,%2\n" \ | 144 | return 1; |
173 | "1: lgr 3,2\n" \ | 145 | return _raw_read_trylock_retry(rw); |
174 | " bctgr 3,0\n" /* one less reader */ \ | 146 | } |
175 | " csg 2,3,0(%1)\n" \ | 147 | |
176 | " jl 0b" \ | 148 | static inline int _raw_write_trylock(rwlock_t *rw) |
177 | : "=m" ((rw)->lock) \ | ||
178 | : "a" (&(rw)->lock), "i" (__DIAG44_OPERAND), \ | ||
179 | "m" ((rw)->lock) : "2", "3", "cc", "memory" ) | ||
180 | #endif /* __s390x__ */ | ||
181 | |||
182 | #ifndef __s390x__ | ||
183 | #define _raw_write_lock(rw) \ | ||
184 | asm volatile(" lhi 3,1\n" \ | ||
185 | " sll 3,31\n" /* new lock value = 0x80000000 */ \ | ||
186 | " j 1f\n" \ | ||
187 | "0: diag 0,0,68\n" \ | ||
188 | "1: slr 2,2\n" /* old lock value must be 0 */ \ | ||
189 | " cs 2,3,0(%1)\n" \ | ||
190 | " jl 0b" \ | ||
191 | : "=m" ((rw)->lock) : "a" (&(rw)->lock), \ | ||
192 | "m" ((rw)->lock) : "2", "3", "cc", "memory" ) | ||
193 | #else /* __s390x__ */ | ||
194 | #define _raw_write_lock(rw) \ | ||
195 | asm volatile(" llihh 3,0x8000\n" /* new lock value = 0x80...0 */ \ | ||
196 | " j 1f\n" \ | ||
197 | "0: " __DIAG44_INSN " 0,%2\n" \ | ||
198 | "1: slgr 2,2\n" /* old lock value must be 0 */ \ | ||
199 | " csg 2,3,0(%1)\n" \ | ||
200 | " jl 0b" \ | ||
201 | : "=m" ((rw)->lock) \ | ||
202 | : "a" (&(rw)->lock), "i" (__DIAG44_OPERAND), \ | ||
203 | "m" ((rw)->lock) : "2", "3", "cc", "memory" ) | ||
204 | #endif /* __s390x__ */ | ||
205 | |||
206 | #ifndef __s390x__ | ||
207 | #define _raw_write_unlock(rw) \ | ||
208 | asm volatile(" slr 3,3\n" /* new lock value = 0 */ \ | ||
209 | " j 1f\n" \ | ||
210 | "0: diag 0,0,68\n" \ | ||
211 | "1: lhi 2,1\n" \ | ||
212 | " sll 2,31\n" /* old lock value must be 0x80000000 */ \ | ||
213 | " cs 2,3,0(%1)\n" \ | ||
214 | " jl 0b" \ | ||
215 | : "=m" ((rw)->lock) : "a" (&(rw)->lock), \ | ||
216 | "m" ((rw)->lock) : "2", "3", "cc", "memory" ) | ||
217 | #else /* __s390x__ */ | ||
218 | #define _raw_write_unlock(rw) \ | ||
219 | asm volatile(" slgr 3,3\n" /* new lock value = 0 */ \ | ||
220 | " j 1f\n" \ | ||
221 | "0: " __DIAG44_INSN " 0,%2\n" \ | ||
222 | "1: llihh 2,0x8000\n" /* old lock value must be 0x8..0 */\ | ||
223 | " csg 2,3,0(%1)\n" \ | ||
224 | " jl 0b" \ | ||
225 | : "=m" ((rw)->lock) \ | ||
226 | : "a" (&(rw)->lock), "i" (__DIAG44_OPERAND), \ | ||
227 | "m" ((rw)->lock) : "2", "3", "cc", "memory" ) | ||
228 | #endif /* __s390x__ */ | ||
229 | |||
230 | #define _raw_read_trylock(lock) generic_raw_read_trylock(lock) | ||
231 | |||
232 | extern inline int _raw_write_trylock(rwlock_t *rw) | ||
233 | { | 149 | { |
234 | unsigned long result, reg; | 150 | if (likely(_raw_compare_and_swap(&rw->lock, 0, 0x80000000) == 0)) |
235 | 151 | return 1; | |
236 | __asm__ __volatile__( | 152 | return _raw_write_trylock_retry(rw); |
237 | #ifndef __s390x__ | ||
238 | " lhi %1,1\n" | ||
239 | " sll %1,31\n" | ||
240 | " cs %0,%1,0(%3)" | ||
241 | #else /* __s390x__ */ | ||
242 | " llihh %1,0x8000\n" | ||
243 | "0: csg %0,%1,0(%3)\n" | ||
244 | #endif /* __s390x__ */ | ||
245 | : "=d" (result), "=&d" (reg), "=m" (rw->lock) | ||
246 | : "a" (&rw->lock), "m" (rw->lock), "0" (0UL) | ||
247 | : "cc", "memory" ); | ||
248 | return result == 0; | ||
249 | } | 153 | } |
250 | 154 | ||
251 | #endif /* __ASM_SPINLOCK_H */ | 155 | #endif /* __ASM_SPINLOCK_H */ |
diff --git a/include/asm-s390/system.h b/include/asm-s390/system.h index 81514d76edcf..864cae7e1fd6 100644 --- a/include/asm-s390/system.h +++ b/include/asm-s390/system.h | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <asm/types.h> | 16 | #include <asm/types.h> |
17 | #include <asm/ptrace.h> | 17 | #include <asm/ptrace.h> |
18 | #include <asm/setup.h> | 18 | #include <asm/setup.h> |
19 | #include <asm/processor.h> | ||
19 | 20 | ||
20 | #ifdef __KERNEL__ | 21 | #ifdef __KERNEL__ |
21 | 22 | ||
@@ -103,29 +104,16 @@ static inline void restore_access_regs(unsigned int *acrs) | |||
103 | prev = __switch_to(prev,next); \ | 104 | prev = __switch_to(prev,next); \ |
104 | } while (0) | 105 | } while (0) |
105 | 106 | ||
106 | #define prepare_arch_switch(rq, next) do { } while(0) | ||
107 | #define task_running(rq, p) ((rq)->curr == (p)) | ||
108 | |||
109 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 107 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
110 | extern void account_user_vtime(struct task_struct *); | 108 | extern void account_user_vtime(struct task_struct *); |
111 | extern void account_system_vtime(struct task_struct *); | 109 | extern void account_system_vtime(struct task_struct *); |
110 | #endif | ||
112 | 111 | ||
113 | #define finish_arch_switch(rq, prev) do { \ | 112 | #define finish_arch_switch(prev) do { \ |
114 | set_fs(current->thread.mm_segment); \ | 113 | set_fs(current->thread.mm_segment); \ |
115 | spin_unlock(&(rq)->lock); \ | ||
116 | account_system_vtime(prev); \ | 114 | account_system_vtime(prev); \ |
117 | local_irq_enable(); \ | ||
118 | } while (0) | 115 | } while (0) |
119 | 116 | ||
120 | #else | ||
121 | |||
122 | #define finish_arch_switch(rq, prev) do { \ | ||
123 | set_fs(current->thread.mm_segment); \ | ||
124 | spin_unlock_irq(&(rq)->lock); \ | ||
125 | } while (0) | ||
126 | |||
127 | #endif | ||
128 | |||
129 | #define nop() __asm__ __volatile__ ("nop") | 117 | #define nop() __asm__ __volatile__ ("nop") |
130 | 118 | ||
131 | #define xchg(ptr,x) \ | 119 | #define xchg(ptr,x) \ |
@@ -331,9 +319,6 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) | |||
331 | 319 | ||
332 | #ifdef __s390x__ | 320 | #ifdef __s390x__ |
333 | 321 | ||
334 | #define __load_psw(psw) \ | ||
335 | __asm__ __volatile__("lpswe 0(%0)" : : "a" (&psw), "m" (psw) : "cc" ); | ||
336 | |||
337 | #define __ctl_load(array, low, high) ({ \ | 322 | #define __ctl_load(array, low, high) ({ \ |
338 | typedef struct { char _[sizeof(array)]; } addrtype; \ | 323 | typedef struct { char _[sizeof(array)]; } addrtype; \ |
339 | __asm__ __volatile__ ( \ | 324 | __asm__ __volatile__ ( \ |
@@ -390,9 +375,6 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) | |||
390 | 375 | ||
391 | #else /* __s390x__ */ | 376 | #else /* __s390x__ */ |
392 | 377 | ||
393 | #define __load_psw(psw) \ | ||
394 | __asm__ __volatile__("lpsw 0(%0)" : : "a" (&psw) : "cc" ); | ||
395 | |||
396 | #define __ctl_load(array, low, high) ({ \ | 378 | #define __ctl_load(array, low, high) ({ \ |
397 | typedef struct { char _[sizeof(array)]; } addrtype; \ | 379 | typedef struct { char _[sizeof(array)]; } addrtype; \ |
398 | __asm__ __volatile__ ( \ | 380 | __asm__ __volatile__ ( \ |
@@ -451,6 +433,20 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) | |||
451 | /* For spinlocks etc */ | 433 | /* For spinlocks etc */ |
452 | #define local_irq_save(x) ((x) = local_irq_disable()) | 434 | #define local_irq_save(x) ((x) = local_irq_disable()) |
453 | 435 | ||
436 | /* | ||
437 | * Use to set psw mask except for the first byte which | ||
438 | * won't be changed by this function. | ||
439 | */ | ||
440 | static inline void | ||
441 | __set_psw_mask(unsigned long mask) | ||
442 | { | ||
443 | local_save_flags(mask); | ||
444 | __load_psw_mask(mask); | ||
445 | } | ||
446 | |||
447 | #define local_mcck_enable() __set_psw_mask(PSW_KERNEL_BITS) | ||
448 | #define local_mcck_disable() __set_psw_mask(PSW_KERNEL_BITS & ~PSW_MASK_MCHECK) | ||
449 | |||
454 | #ifdef CONFIG_SMP | 450 | #ifdef CONFIG_SMP |
455 | 451 | ||
456 | extern void smp_ctl_set_bit(int cr, int bit); | 452 | extern void smp_ctl_set_bit(int cr, int bit); |
diff --git a/include/asm-s390/thread_info.h b/include/asm-s390/thread_info.h index aade85c53a63..6c18a3f24316 100644 --- a/include/asm-s390/thread_info.h +++ b/include/asm-s390/thread_info.h | |||
@@ -50,7 +50,7 @@ struct thread_info { | |||
50 | struct exec_domain *exec_domain; /* execution domain */ | 50 | struct exec_domain *exec_domain; /* execution domain */ |
51 | unsigned long flags; /* low level flags */ | 51 | unsigned long flags; /* low level flags */ |
52 | unsigned int cpu; /* current CPU */ | 52 | unsigned int cpu; /* current CPU */ |
53 | unsigned int preempt_count; /* 0 => preemptable */ | 53 | int preempt_count; /* 0 => preemptable, <0 => BUG */ |
54 | struct restart_block restart_block; | 54 | struct restart_block restart_block; |
55 | }; | 55 | }; |
56 | 56 | ||
@@ -96,6 +96,7 @@ static inline struct thread_info *current_thread_info(void) | |||
96 | #define TIF_RESTART_SVC 4 /* restart svc with new svc number */ | 96 | #define TIF_RESTART_SVC 4 /* restart svc with new svc number */ |
97 | #define TIF_SYSCALL_AUDIT 5 /* syscall auditing active */ | 97 | #define TIF_SYSCALL_AUDIT 5 /* syscall auditing active */ |
98 | #define TIF_SINGLE_STEP 6 /* deliver sigtrap on return to user */ | 98 | #define TIF_SINGLE_STEP 6 /* deliver sigtrap on return to user */ |
99 | #define TIF_MCCK_PENDING 7 /* machine check handling is pending */ | ||
99 | #define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */ | 100 | #define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */ |
100 | #define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling | 101 | #define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling |
101 | TIF_NEED_RESCHED */ | 102 | TIF_NEED_RESCHED */ |
@@ -109,6 +110,7 @@ static inline struct thread_info *current_thread_info(void) | |||
109 | #define _TIF_RESTART_SVC (1<<TIF_RESTART_SVC) | 110 | #define _TIF_RESTART_SVC (1<<TIF_RESTART_SVC) |
110 | #define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT) | 111 | #define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT) |
111 | #define _TIF_SINGLE_STEP (1<<TIF_SINGLE_STEP) | 112 | #define _TIF_SINGLE_STEP (1<<TIF_SINGLE_STEP) |
113 | #define _TIF_MCCK_PENDING (1<<TIF_MCCK_PENDING) | ||
112 | #define _TIF_USEDFPU (1<<TIF_USEDFPU) | 114 | #define _TIF_USEDFPU (1<<TIF_USEDFPU) |
113 | #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) | 115 | #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) |
114 | #define _TIF_31BIT (1<<TIF_31BIT) | 116 | #define _TIF_31BIT (1<<TIF_31BIT) |
diff --git a/include/asm-s390/uaccess.h b/include/asm-s390/uaccess.h index a7f43a251f81..3e3bfe6a8fa8 100644 --- a/include/asm-s390/uaccess.h +++ b/include/asm-s390/uaccess.h | |||
@@ -149,11 +149,11 @@ struct exception_table_entry | |||
149 | }) | 149 | }) |
150 | #endif | 150 | #endif |
151 | 151 | ||
152 | #ifndef __CHECKER__ | ||
153 | #define __put_user(x, ptr) \ | 152 | #define __put_user(x, ptr) \ |
154 | ({ \ | 153 | ({ \ |
155 | __typeof__(*(ptr)) __x = (x); \ | 154 | __typeof__(*(ptr)) __x = (x); \ |
156 | int __pu_err; \ | 155 | int __pu_err; \ |
156 | __chk_user_ptr(ptr); \ | ||
157 | switch (sizeof (*(ptr))) { \ | 157 | switch (sizeof (*(ptr))) { \ |
158 | case 1: \ | 158 | case 1: \ |
159 | case 2: \ | 159 | case 2: \ |
@@ -167,14 +167,6 @@ struct exception_table_entry | |||
167 | } \ | 167 | } \ |
168 | __pu_err; \ | 168 | __pu_err; \ |
169 | }) | 169 | }) |
170 | #else | ||
171 | #define __put_user(x, ptr) \ | ||
172 | ({ \ | ||
173 | void __user *p; \ | ||
174 | p = (ptr); \ | ||
175 | 0; \ | ||
176 | }) | ||
177 | #endif | ||
178 | 170 | ||
179 | #define put_user(x, ptr) \ | 171 | #define put_user(x, ptr) \ |
180 | ({ \ | 172 | ({ \ |
@@ -213,11 +205,11 @@ extern int __put_user_bad(void) __attribute__((noreturn)); | |||
213 | }) | 205 | }) |
214 | #endif | 206 | #endif |
215 | 207 | ||
216 | #ifndef __CHECKER__ | ||
217 | #define __get_user(x, ptr) \ | 208 | #define __get_user(x, ptr) \ |
218 | ({ \ | 209 | ({ \ |
219 | __typeof__(*(ptr)) __x; \ | 210 | __typeof__(*(ptr)) __x; \ |
220 | int __gu_err; \ | 211 | int __gu_err; \ |
212 | __chk_user_ptr(ptr); \ | ||
221 | switch (sizeof(*(ptr))) { \ | 213 | switch (sizeof(*(ptr))) { \ |
222 | case 1: \ | 214 | case 1: \ |
223 | case 2: \ | 215 | case 2: \ |
@@ -232,15 +224,6 @@ extern int __put_user_bad(void) __attribute__((noreturn)); | |||
232 | (x) = __x; \ | 224 | (x) = __x; \ |
233 | __gu_err; \ | 225 | __gu_err; \ |
234 | }) | 226 | }) |
235 | #else | ||
236 | #define __get_user(x, ptr) \ | ||
237 | ({ \ | ||
238 | void __user *p; \ | ||
239 | p = (ptr); \ | ||
240 | 0; \ | ||
241 | }) | ||
242 | #endif | ||
243 | |||
244 | 227 | ||
245 | #define get_user(x, ptr) \ | 228 | #define get_user(x, ptr) \ |
246 | ({ \ | 229 | ({ \ |
diff --git a/include/asm-s390/unistd.h b/include/asm-s390/unistd.h index f1a204f7c0f0..221e965da924 100644 --- a/include/asm-s390/unistd.h +++ b/include/asm-s390/unistd.h | |||
@@ -269,13 +269,18 @@ | |||
269 | #define __NR_mq_timedreceive 274 | 269 | #define __NR_mq_timedreceive 274 |
270 | #define __NR_mq_notify 275 | 270 | #define __NR_mq_notify 275 |
271 | #define __NR_mq_getsetattr 276 | 271 | #define __NR_mq_getsetattr 276 |
272 | /* Number 277 is reserved for new sys_kexec_load */ | 272 | #define __NR_kexec_load 277 |
273 | #define __NR_add_key 278 | 273 | #define __NR_add_key 278 |
274 | #define __NR_request_key 279 | 274 | #define __NR_request_key 279 |
275 | #define __NR_keyctl 280 | 275 | #define __NR_keyctl 280 |
276 | #define __NR_waitid 281 | 276 | #define __NR_waitid 281 |
277 | #define __NR_ioprio_set 282 | ||
278 | #define __NR_ioprio_get 283 | ||
279 | #define __NR_inotify_init 284 | ||
280 | #define __NR_inotify_add_watch 285 | ||
281 | #define __NR_inotify_rm_watch 286 | ||
277 | 282 | ||
278 | #define NR_syscalls 282 | 283 | #define NR_syscalls 287 |
279 | 284 | ||
280 | /* | 285 | /* |
281 | * There are some system calls that are not present on 64 bit, some | 286 | * There are some system calls that are not present on 64 bit, some |