aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-s390
diff options
context:
space:
mode:
Diffstat (limited to 'include/asm-s390')
-rw-r--r--include/asm-s390/atomic.h8
-rw-r--r--include/asm-s390/bitops.h440
-rw-r--r--include/asm-s390/cpcmd.h18
-rw-r--r--include/asm-s390/debug.h48
-rw-r--r--include/asm-s390/emergency-restart.h6
-rw-r--r--include/asm-s390/kexec.h42
-rw-r--r--include/asm-s390/lowcore.h11
-rw-r--r--include/asm-s390/processor.h57
-rw-r--r--include/asm-s390/ptrace.h2
-rw-r--r--include/asm-s390/spinlock.h252
-rw-r--r--include/asm-s390/system.h38
-rw-r--r--include/asm-s390/thread_info.h4
-rw-r--r--include/asm-s390/uaccess.h21
-rw-r--r--include/asm-s390/unistd.h9
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
126static __inline__ void atomic64_add(int i, atomic64_t * v) 126static __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}
130static __inline__ long long atomic64_add_return(int i, atomic64_t * v) 130static __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}
134static __inline__ long long atomic64_add_negative(int i, atomic64_t * v) 134static __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}
138static __inline__ void atomic64_sub(int i, atomic64_t * v) 138static __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 */
534static 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 */
559static 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
535static inline int 586static inline int
536find_first_zero_bit(const unsigned long * addr, unsigned int size) 587find_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
576static inline int 627static inline int
577find_first_bit(const unsigned long * addr, unsigned int size) 628find_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
617static inline int
618find_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
656static inline int
657find_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 */
700static inline unsigned long 670static inline unsigned long
701find_first_zero_bit(const unsigned long * addr, unsigned long size) 671find_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
788static inline unsigned long
789find_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
832static inline unsigned long
833find_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/* 760static inline int
878 * ffz = Find First Zero in word. Undefined if no zero exists, 761find_next_zero_bit (const unsigned long * addr, unsigned long size,
879 * so code should check against ~0UL first.. 762 unsigned long offset)
880 */
881static 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/* 790static inline int
903 * __ffs = find first bit in word. Undefined if no bit exists, 791find_next_bit (const unsigned long * addr, unsigned long size,
904 * so code should check against 0UL first.. 792 unsigned long offset)
905 */
906static 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
1034static inline int
1035ext2_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
1079static inline unsigned long 929static 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
1123static inline unsigned long 973#endif /* __s390x__ */
974
975static inline int
1124ext2_find_next_zero_bit(void *vaddr, unsigned long size, unsigned long offset) 976ext2_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 */
16extern void __cpcmd(char *cmd, char *response, int rlen); 17extern 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
21extern 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 */
35extern 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
79typedef int (debug_header_proc_t) (debug_info_t* id, 81typedef 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
100struct debug_view { 102struct 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
123debug_info_t* debug_register(char* name, int pages_index, int nr_areas, 125debug_info_t* debug_register(char* name, int pages, int nr_areas,
124 int buf_size); 126 int buf_size);
125 127
126void debug_unregister(debug_info_t* id); 128void debug_unregister(debug_info_t* id);
@@ -132,7 +134,8 @@ void debug_stop_all(void);
132extern inline debug_entry_t* 134extern inline debug_entry_t*
133debug_event(debug_info_t* id, int level, void* data, int length) 135debug_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*
140debug_int_event(debug_info_t* id, int level, unsigned int tag) 143debug_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 *
148debug_long_event (debug_info_t* id, int level, unsigned long tag) 152debug_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
155extern inline debug_entry_t* 160extern inline debug_entry_t*
156debug_text_event(debug_info_t* id, int level, const char* txt) 161debug_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,...)
167extern inline debug_entry_t* 173extern inline debug_entry_t*
168debug_exception(debug_info_t* id, int level, void* data, int length) 174debug_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*
175debug_int_exception(debug_info_t* id, int level, unsigned int tag) 182debug_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 *
183debug_long_exception (debug_info_t* id, int level, unsigned long tag) 191debug_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
190extern inline debug_entry_t* 199extern inline debug_entry_t*
191debug_text_exception(debug_info_t* id, int level, const char* txt) 200debug_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
38typedef u32 note_buf_t[MAX_NOTE_BYTES/4];
39
40extern 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 */
215static 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);
214static inline void __load_psw_mask (unsigned long mask) 229static 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 */
242static inline void enabled_wait(void) 257static 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
274static inline void disabled_wait(unsigned long code) 267static 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__ 14static 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
50extern inline void _raw_spin_lock(spinlock_t *lp) 45extern void _raw_spin_lock_wait(spinlock_t *lp, unsigned int pc);
46extern int _raw_spin_trylock_retry(spinlock_t *lp, unsigned int pc);
47
48static 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
75extern inline int _raw_spin_trylock(spinlock_t *lp) 56static 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
88extern inline void _raw_spin_unlock(spinlock_t *lp) 65static 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 */
108typedef struct { 80typedef 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__ 104extern void _raw_read_lock_wait(rwlock_t *lp);
133#define _raw_read_lock(rw) \ 105extern int _raw_read_trylock_retry(rwlock_t *lp);
134 asm volatile(" l 2,0(%1)\n" \ 106extern void _raw_write_lock_wait(rwlock_t *lp);
135 " j 1f\n" \ 107extern 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 */ \ 109static 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" \ 117static 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 128static 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" \ 134static 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" ) 139static 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" \ 148static 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
232extern 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
110extern void account_user_vtime(struct task_struct *); 108extern void account_user_vtime(struct task_struct *);
111extern void account_system_vtime(struct task_struct *); 109extern 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 */
440static 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
456extern void smp_ctl_set_bit(int cr, int bit); 452extern 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