[PATCH] s390 (15/16): s390/s390x unification - part 6.

From: Martin Schwidefsky (schwidefsky@de.ibm.com)
Date: Mon Apr 14 2003 - 12:54:14 EST


Merge s390x and s390 to one architecture.

diffstat:
 bitops.h | 732 +++++++++++++++++++++++++++++++++++++++++++---------------
 byteorder.h | 55 ++++
 ccwdev.h | 10
 checksum.h | 73 +++++
 compat.h | 122 +++++++++
 div64.h | 13 -
 ebcdic.h | 4
 elf.h | 27 ++
 fcntl.h | 6
 gdb-stub.h | 22 -
 idals.h | 14 -
 io.h | 9
 ipc.h | 1
 ipcbuf.h | 2
 lowcore.h | 144 ++++++++++-
 mmu_context.h | 8
 module.h | 5
 msgbuf.h | 6
 page.h | 69 +++++
 pgalloc.h | 53 ++++
 pgtable.h | 249 +++++++++++++++++--
 21 files changed, 1370 insertions(+), 254 deletions(-)

diff -urN linux-2.5.67/include/asm-s390/bitops.h linux-2.5.67-s390/include/asm-s390/bitops.h
--- linux-2.5.67/include/asm-s390/bitops.h Mon Apr 14 19:11:36 2003
+++ linux-2.5.67-s390/include/asm-s390/bitops.h Mon Apr 14 19:11:58 2003
@@ -15,6 +15,7 @@
 #include <linux/config.h>
 
 /*
+ * 32 bit bitops format:
  * bit 0 is the LSB of *addr; bit 31 is the MSB of *addr;
  * bit 32 is the LSB of *(addr+4). That combined with the
  * big endian byte order on S390 give the following bit
@@ -28,6 +29,25 @@
  * in the architecture independent code bits operations
  * of the form "flags |= (1 << bitnr)" are used INTERMIXED
  * with operation of the form "set_bit(bitnr, flags)".
+ *
+ * 64 bit bitops format:
+ * bit 0 is the LSB of *addr; bit 63 is the MSB of *addr;
+ * bit 64 is the LSB of *(addr+8). That combined with the
+ * big endian byte order on S390 give the following bit
+ * order in memory:
+ * 3f 3e 3d 3c 3b 3a 39 38 37 36 35 34 33 32 31 30
+ * 2f 2e 2d 2c 2b 2a 29 28 27 26 25 24 23 22 21 20
+ * 1f 1e 1d 1c 1b 1a 19 18 17 16 15 14 13 12 11 10
+ * 0f 0e 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00
+ * after that follows the next long with bit numbers
+ * 7f 7e 7d 7c 7b 7a 79 78 77 76 75 74 73 72 71 70
+ * 6f 6e 6d 6c 6b 6a 69 68 67 66 65 64 63 62 61 60
+ * 5f 5e 5d 5c 5b 5a 59 58 57 56 55 54 53 52 51 50
+ * 4f 4e 4d 4c 4b 4a 49 48 47 46 45 44 43 42 41 40
+ * The reason for this bit ordering is the fact that
+ * in the architecture independent code bits operations
+ * of the form "flags |= (1 << bitnr)" are used INTERMIXED
+ * with operation of the form "set_bit(bitnr, flags)".
  */
 
 /* set ALIGN_CS to 1 if the SMP safe bit operations should
@@ -49,106 +69,126 @@
 extern const char _zb_findmap[];
 extern const char _sb_findmap[];
 
+#ifndef __s390x__
+
+#define __BITOPS_ALIGN 3
+#define __BITOPS_WORDSIZE 32
+#define __BITOPS_OR "or"
+#define __BITOPS_AND "nr"
+#define __BITOPS_XOR "xr"
+
+#define __BITOPS_LOOP(__old, __new, __addr, __val, __op_string) \
+ __asm__ __volatile__(" l %0,0(%4)\n" \
+ "0: lr %1,%0\n" \
+ __op_string " %1,%3\n" \
+ " cs %0,%1,0(%4)\n" \
+ " jl 0b" \
+ : "=&d" (__old), "=&d" (__new), \
+ "=m" (*(unsigned long *) __addr) \
+ : "d" (__val), "a" (__addr), \
+ "m" (*(unsigned long *) __addr) : "cc" );
+
+#else /* __s390x__ */
+
+#define __BITOPS_ALIGN 7
+#define __BITOPS_WORDSIZE 64
+#define __BITOPS_OR "ogr"
+#define __BITOPS_AND "ngr"
+#define __BITOPS_XOR "xgr"
+
+#define __BITOPS_LOOP(__old, __new, __addr, __val, __op_string) \
+ __asm__ __volatile__(" lg %0,0(%4)\n" \
+ "0: lgr %1,%0\n" \
+ __op_string " %1,%3\n" \
+ " csg %0,%1,0(%4)\n" \
+ " jl 0b" \
+ : "=&d" (__old), "=&d" (__new), \
+ "=m" (*(unsigned long *) __addr) \
+ : "d" (__val), "a" (__addr), \
+ "m" (*(unsigned long *) __addr) : "cc" );
+
+#endif /* __s390x__ */
+
 #ifdef CONFIG_SMP
 /*
  * SMP safe set_bit routine based on compare and swap (CS)
  */
-static inline void set_bit_cs(int nr, volatile unsigned long *ptr)
+static inline void set_bit_cs(unsigned long nr, volatile unsigned long *ptr)
 {
         unsigned long addr, old, new, mask;
 
         addr = (unsigned long) ptr;
 #if ALIGN_CS == 1
- nr += (addr & 3) << 3; /* add alignment to bit number */
- addr ^= addr & 3; /* align address to 4 */
+ nr += (addr & __BITOPS_ALIGN) << 3; /* add alignment to bit number */
+ addr ^= addr & __BITOPS_ALIGN; /* align address to 8 */
 #endif
- addr += (nr ^ (nr & 31)) >> 3; /* calculate address for CS */
- mask = 1UL << (nr & 31); /* make OR mask */
- asm volatile(
- " l %0,0(%4)\n"
- "0: lr %1,%0\n"
- " or %1,%3\n"
- " cs %0,%1,0(%4)\n"
- " jl 0b"
- : "=&d" (old), "=&d" (new), "+m" (*(unsigned int *) addr)
- : "d" (mask), "a" (addr)
- : "cc" );
+ /* calculate address for CS */
+ addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3;
+ /* make OR mask */
+ mask = 1UL << (nr & (__BITOPS_WORDSIZE - 1));
+ /* Do the atomic update. */
+ __BITOPS_LOOP(old, new, addr, mask, __BITOPS_OR);
 }
 
 /*
  * SMP safe clear_bit routine based on compare and swap (CS)
  */
-static inline void clear_bit_cs(int nr, volatile unsigned long *ptr)
+static inline void clear_bit_cs(unsigned long nr, volatile unsigned long *ptr)
 {
         unsigned long addr, old, new, mask;
 
         addr = (unsigned long) ptr;
 #if ALIGN_CS == 1
- nr += (addr & 3) << 3; /* add alignment to bit number */
- addr ^= addr & 3; /* align address to 4 */
+ nr += (addr & __BITOPS_ALIGN) << 3; /* add alignment to bit number */
+ addr ^= addr & __BITOPS_ALIGN; /* align address to 8 */
 #endif
- addr += (nr ^ (nr & 31)) >> 3; /* calculate address for CS */
- mask = ~(1UL << (nr & 31)); /* make AND mask */
- asm volatile(
- " l %0,0(%4)\n"
- "0: lr %1,%0\n"
- " nr %1,%3\n"
- " cs %0,%1,0(%4)\n"
- " jl 0b"
- : "=&d" (old), "=&d" (new), "+m" (*(unsigned int *) addr)
- : "d" (mask), "a" (addr)
- : "cc" );
+ /* calculate address for CS */
+ addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3;
+ /* make AND mask */
+ mask = ~(1UL << (nr & (__BITOPS_WORDSIZE - 1)));
+ /* Do the atomic update. */
+ __BITOPS_LOOP(old, new, addr, mask, __BITOPS_AND);
 }
 
 /*
  * SMP safe change_bit routine based on compare and swap (CS)
  */
-static inline void change_bit_cs(int nr, volatile unsigned long *ptr)
+static inline void change_bit_cs(unsigned long nr, volatile unsigned long *ptr)
 {
         unsigned long addr, old, new, mask;
 
         addr = (unsigned long) ptr;
 #if ALIGN_CS == 1
- nr += (addr & 3) << 3; /* add alignment to bit number */
- addr ^= addr & 3; /* align address to 4 */
+ nr += (addr & __BITOPS_ALIGN) << 3; /* add alignment to bit number */
+ addr ^= addr & __BITOPS_ALIGN; /* align address to 8 */
 #endif
- addr += (nr ^ (nr & 31)) >> 3; /* calculate address for CS */
- mask = 1UL << (nr & 31); /* make XOR mask */
- asm volatile(
- " l %0,0(%4)\n"
- "0: lr %1,%0\n"
- " xr %1,%3\n"
- " cs %0,%1,0(%4)\n"
- " jl 0b"
- : "=&d" (old), "=&d" (new), "+m" (*(unsigned int *) addr)
- : "d" (mask), "a" (addr)
- : "cc" );
+ /* calculate address for CS */
+ addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3;
+ /* make XOR mask */
+ mask = 1UL << (nr & (__BITOPS_WORDSIZE - 1));
+ /* Do the atomic update. */
+ __BITOPS_LOOP(old, new, addr, mask, __BITOPS_XOR);
 }
 
 /*
  * SMP safe test_and_set_bit routine based on compare and swap (CS)
  */
 static inline int
-test_and_set_bit_cs(int nr, volatile unsigned long *ptr)
+test_and_set_bit_cs(unsigned long nr, volatile unsigned long *ptr)
 {
         unsigned long addr, old, new, mask;
 
         addr = (unsigned long) ptr;
 #if ALIGN_CS == 1
- addr ^= addr & 3; /* align address to 4 */
- nr += (addr & 3) << 3; /* add alignment to bit number */
+ nr += (addr & __BITOPS_ALIGN) << 3; /* add alignment to bit number */
+ addr ^= addr & __BITOPS_ALIGN; /* align address to 8 */
 #endif
- addr += (nr ^ (nr & 31)) >> 3; /* calculate address for CS */
- mask = 1UL << (nr & 31); /* make OR/test mask */
- asm volatile(
- " l %0,0(%4)\n"
- "0: lr %1,%0\n"
- " or %1,%3\n"
- " cs %0,%1,0(%4)\n"
- " jl 0b"
- : "=&d" (old), "=&d" (new), "+m" (*(unsigned int *) addr)
- : "d" (mask), "a" (addr)
- : "cc" );
+ /* calculate address for CS */
+ addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3;
+ /* make OR/test mask */
+ mask = 1UL << (nr & (__BITOPS_WORDSIZE - 1));
+ /* Do the atomic update. */
+ __BITOPS_LOOP(old, new, addr, mask, __BITOPS_OR);
         return (old & mask) != 0;
 }
 
@@ -156,26 +196,21 @@
  * SMP safe test_and_clear_bit routine based on compare and swap (CS)
  */
 static inline int
-test_and_clear_bit_cs(int nr, volatile unsigned long *ptr)
+test_and_clear_bit_cs(unsigned long nr, volatile unsigned long *ptr)
 {
         unsigned long addr, old, new, mask;
 
         addr = (unsigned long) ptr;
 #if ALIGN_CS == 1
- nr += (addr & 3) << 3; /* add alignment to bit number */
- addr ^= addr & 3; /* align address to 4 */
+ nr += (addr & __BITOPS_ALIGN) << 3; /* add alignment to bit number */
+ addr ^= addr & __BITOPS_ALIGN; /* align address to 8 */
 #endif
- addr += (nr ^ (nr & 31)) >> 3; /* calculate address for CS */
- mask = ~(1UL << (nr & 31)); /* make AND mask */
- asm volatile(
- " l %0,0(%4)\n"
- "0: lr %1,%0\n"
- " nr %1,%3\n"
- " cs %0,%1,0(%4)\n"
- " jl 0b"
- : "=&d" (old), "=&d" (new), "+m" (*(unsigned int *) addr)
- : "d" (mask), "a" (addr)
- : "cc" );
+ /* calculate address for CS */
+ addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3;
+ /* make AND/test mask */
+ mask = ~(1UL << (nr & (__BITOPS_WORDSIZE - 1)));
+ /* Do the atomic update. */
+ __BITOPS_LOOP(old, new, addr, mask, __BITOPS_AND);
         return (old ^ new) != 0;
 }
 
@@ -183,26 +218,21 @@
  * SMP safe test_and_change_bit routine based on compare and swap (CS)
  */
 static inline int
-test_and_change_bit_cs(int nr, volatile unsigned long *ptr)
+test_and_change_bit_cs(unsigned long nr, volatile unsigned long *ptr)
 {
         unsigned long addr, old, new, mask;
 
         addr = (unsigned long) ptr;
 #if ALIGN_CS == 1
- nr += (addr & 3) << 3; /* add alignment to bit number */
- addr ^= addr & 3; /* align address to 4 */
+ nr += (addr & __BITOPS_ALIGN) << 3; /* add alignment to bit number */
+ addr ^= addr & __BITOPS_ALIGN; /* align address to 8 */
 #endif
- addr += (nr ^ (nr & 31)) >> 3; /* calculate address for CS */
- mask = 1UL << (nr & 31); /* make XOR mask */
- asm volatile(
- " l %0,0(%4)\n"
- "0: lr %1,%0\n"
- " xr %1,%3\n"
- " cs %0,%1,0(%4)\n"
- " jl 0b"
- : "=&d" (old), "=&d" (new), "+m" (*(unsigned int *) addr)
- : "d" (mask), "a" (addr)
- : "cc" );
+ /* calculate address for CS */
+ addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3;
+ /* make XOR/test mask */
+ mask = 1UL << (nr & (__BITOPS_WORDSIZE - 1));
+ /* Do the atomic update. */
+ __BITOPS_LOOP(old, new, addr, mask, __BITOPS_XOR);
         return (old & mask) != 0;
 }
 #endif /* CONFIG_SMP */
@@ -210,55 +240,55 @@
 /*
  * fast, non-SMP set_bit routine
  */
-static inline void __set_bit(int nr, volatile unsigned long *ptr)
+static inline void __set_bit(unsigned long nr, volatile unsigned long *ptr)
 {
         unsigned long addr;
 
- addr = (unsigned long) ptr + ((nr ^ 24) >> 3);
+ addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
         asm volatile("oc 0(1,%1),0(%2)"
- : "+m" (*(char *) addr)
- : "a" (addr), "a" (_oi_bitmap + (nr & 7))
- : "cc" );
+ : "=m" (*(char *) addr)
+ : "a" (addr), "a" (_oi_bitmap + (nr & 7)),
+ "m" (*(char *) addr) : "cc" );
 }
 
 static inline void
-__constant_set_bit(const int nr, volatile unsigned long *ptr)
+__constant_set_bit(const unsigned long nr, volatile unsigned long *ptr)
 {
         unsigned long addr;
 
- addr = ((unsigned long) ptr) + ((nr >> 3) ^ 3);
+ addr = ((unsigned long) ptr) + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
         switch (nr&7) {
         case 0:
- asm volatile ("oi 0(%1),0x01"
- : "+m" (*(char *) addr) : "a" (addr) : "cc" );
+ asm volatile ("oi 0(%1),0x01" : "=m" (*(char *) addr)
+ : "a" (addr), "m" (*(char *) addr) : "cc" );
                 break;
         case 1:
- asm volatile ("oi 0(%1),0x02"
- : "+m" (*(char *) addr) : "a" (addr) : "cc" );
+ asm volatile ("oi 0(%1),0x02" : "=m" (*(char *) addr)
+ : "a" (addr), "m" (*(char *) addr) : "cc" );
                 break;
         case 2:
- asm volatile ("oi 0(%1),0x04"
- : "+m" (*(char *) addr) : "a" (addr) : "cc" );
+ asm volatile ("oi 0(%1),0x04" : "=m" (*(char *) addr)
+ : "a" (addr), "m" (*(char *) addr) : "cc" );
                 break;
         case 3:
- asm volatile ("oi 0(%1),0x08"
- : "+m" (*(char *) addr) : "a" (addr) : "cc" );
+ asm volatile ("oi 0(%1),0x08" : "=m" (*(char *) addr)
+ : "a" (addr), "m" (*(char *) addr) : "cc" );
                 break;
         case 4:
- asm volatile ("oi 0(%1),0x10"
- : "+m" (*(char *) addr) : "a" (addr) : "cc" );
+ asm volatile ("oi 0(%1),0x10" : "=m" (*(char *) addr)
+ : "a" (addr), "m" (*(char *) addr) : "cc" );
                 break;
         case 5:
- asm volatile ("oi 0(%1),0x20"
- : "+m" (*(char *) addr) : "a" (addr) : "cc" );
+ asm volatile ("oi 0(%1),0x20" : "=m" (*(char *) addr)
+ : "a" (addr), "m" (*(char *) addr) : "cc" );
                 break;
         case 6:
- asm volatile ("oi 0(%1),0x40"
- : "+m" (*(char *) addr) : "a" (addr) : "cc" );
+ asm volatile ("oi 0(%1),0x40" : "=m" (*(char *) addr)
+ : "a" (addr), "m" (*(char *) addr) : "cc" );
                 break;
         case 7:
- asm volatile ("oi 0(%1),0x80"
- : "+m" (*(char *) addr) : "a" (addr) : "cc" );
+ asm volatile ("oi 0(%1),0x80" : "=m" (*(char *) addr)
+ : "a" (addr), "m" (*(char *) addr) : "cc" );
                 break;
         }
 }
@@ -272,55 +302,55 @@
  * fast, non-SMP clear_bit routine
  */
 static inline void
-__clear_bit(int nr, volatile unsigned long *ptr)
+__clear_bit(unsigned long nr, volatile unsigned long *ptr)
 {
         unsigned long addr;
 
- addr = (unsigned long) ptr + ((nr ^ 24) >> 3);
+ addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
         asm volatile("nc 0(1,%1),0(%2)"
- : "+m" (*(char *) addr)
- : "a" (addr), "a" (_ni_bitmap + (nr & 7))
- : "cc" );
+ : "=m" (*(char *) addr)
+ : "a" (addr), "a" (_ni_bitmap + (nr & 7)),
+ "m" (*(char *) addr) : "cc" );
 }
 
 static inline void
-__constant_clear_bit(const int nr, volatile unsigned long *ptr)
+__constant_clear_bit(const unsigned long nr, volatile unsigned long *ptr)
 {
         unsigned long addr;
 
- addr = ((unsigned long) ptr) + ((nr >> 3) ^ 3);
+ addr = ((unsigned long) ptr) + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
         switch (nr&7) {
         case 0:
- asm volatile ("ni 0(%1),0xFE"
- : "+m" (*(char *) addr) : "a" (addr) : "cc" );
+ asm volatile ("ni 0(%1),0xFE" : "=m" (*(char *) addr)
+ : "a" (addr), "m" (*(char *) addr) : "cc" );
                 break;
         case 1:
- asm volatile ("ni 0(%1),0xFD"
- : "+m" (*(char *) addr) : "a" (addr) : "cc" );
+ asm volatile ("ni 0(%1),0xFD": "=m" (*(char *) addr)
+ : "a" (addr), "m" (*(char *) addr) : "cc" );
                 break;
         case 2:
- asm volatile ("ni 0(%1),0xFB"
- : "+m" (*(char *) addr) : "a" (addr) : "cc" );
+ asm volatile ("ni 0(%1),0xFB" : "=m" (*(char *) addr)
+ : "a" (addr), "m" (*(char *) addr) : "cc" );
                 break;
         case 3:
- asm volatile ("ni 0(%1),0xF7"
- : "+m" (*(char *) addr) : "a" (addr) : "cc" );
+ asm volatile ("ni 0(%1),0xF7" : "=m" (*(char *) addr)
+ : "a" (addr), "m" (*(char *) addr) : "cc" );
                 break;
         case 4:
- asm volatile ("ni 0(%1),0xEF"
- : "+m" (*(char *) addr) : "a" (addr) : "cc" );
+ asm volatile ("ni 0(%1),0xEF" : "=m" (*(char *) addr)
+ : "a" (addr), "m" (*(char *) addr) : "cc" );
                 break;
         case 5:
- asm volatile ("ni 0(%1),0xDF"
- : "+m" (*(char *) addr) : "a" (addr) : "cc" );
+ asm volatile ("ni 0(%1),0xDF" : "=m" (*(char *) addr)
+ : "a" (addr), "m" (*(char *) addr) : "cc" );
                 break;
         case 6:
- asm volatile ("ni 0(%1),0xBF"
- : "+m" (*(char *) addr) : "a" (addr) : "cc" );
+ asm volatile ("ni 0(%1),0xBF" : "=m" (*(char *) addr)
+ : "a" (addr), "m" (*(char *) addr) : "cc" );
                 break;
         case 7:
- asm volatile ("ni 0(%1),0x7F"
- : "+m" (*(char *) addr) : "a" (addr) : "cc" );
+ asm volatile ("ni 0(%1),0x7F" : "=m" (*(char *) addr)
+ : "a" (addr), "m" (*(char *) addr) : "cc" );
                 break;
         }
 }
@@ -333,55 +363,55 @@
 /*
  * fast, non-SMP change_bit routine
  */
-static inline void __change_bit(int nr, volatile unsigned long *ptr)
+static inline void __change_bit(unsigned long nr, volatile unsigned long *ptr)
 {
         unsigned long addr;
 
- addr = (unsigned long) ptr + ((nr ^ 24) >> 3);
+ addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
         asm volatile("xc 0(1,%1),0(%2)"
- : "+m" (*(char *) addr)
- : "a" (addr), "a" (_oi_bitmap + (nr & 7))
- : "cc" );
+ : "=m" (*(char *) addr)
+ : "a" (addr), "a" (_oi_bitmap + (nr & 7)),
+ "m" (*(char *) addr) : "cc" );
 }
 
 static inline void
-__constant_change_bit(const int nr, volatile unsigned long *ptr)
+__constant_change_bit(const unsigned long nr, volatile unsigned long *ptr)
 {
         unsigned long addr;
 
- addr = ((unsigned long) ptr) + ((nr >> 3) ^ 3);
+ addr = ((unsigned long) ptr) + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
         switch (nr&7) {
         case 0:
- asm volatile ("xi 0(%1),0x01"
- : "+m" (*(char *) addr) : "a" (addr) : "cc" );
+ asm volatile ("xi 0(%1),0x01" : "=m" (*(char *) addr)
+ : "a" (addr), "m" (*(char *) addr) : "cc" );
                 break;
         case 1:
- asm volatile ("xi 0(%1),0x02"
- : "+m" (*(char *) addr) : "a" (addr) : "cc" );
+ asm volatile ("xi 0(%1),0x02" : "=m" (*(char *) addr)
+ : "a" (addr), "m" (*(char *) addr) : "cc" );
                 break;
         case 2:
- asm volatile ("xi 0(%1),0x04"
- : "+m" (*(char *) addr) : "a" (addr) : "cc" );
+ asm volatile ("xi 0(%1),0x04" : "=m" (*(char *) addr)
+ : "a" (addr), "m" (*(char *) addr) : "cc" );
                 break;
         case 3:
- asm volatile ("xi 0(%1),0x08"
- : "+m" (*(char *) addr) : "a" (addr) : "cc" );
+ asm volatile ("xi 0(%1),0x08" : "=m" (*(char *) addr)
+ : "a" (addr), "m" (*(char *) addr) : "cc" );
                 break;
         case 4:
- asm volatile ("xi 0(%1),0x10"
- : "+m" (*(char *) addr) : "a" (addr) : "cc" );
+ asm volatile ("xi 0(%1),0x10" : "=m" (*(char *) addr)
+ : "a" (addr), "m" (*(char *) addr) : "cc" );
                 break;
         case 5:
- asm volatile ("xi 0(%1),0x20"
- : "+m" (*(char *) addr) : "a" (addr) : "cc" );
+ asm volatile ("xi 0(%1),0x20" : "=m" (*(char *) addr)
+ : "a" (addr), "m" (*(char *) addr) : "cc" );
                 break;
         case 6:
- asm volatile ("xi 0(%1),0x40"
- : "+m" (*(char *) addr) : "a" (addr) : "cc" );
+ asm volatile ("xi 0(%1),0x40" : "=m" (*(char *) addr)
+ : "a" (addr), "m" (*(char *) addr) : "cc" );
                 break;
         case 7:
- asm volatile ("xi 0(%1),0x80"
- : "+m" (*(char *) addr) : "a" (addr) : "cc" );
+ asm volatile ("xi 0(%1),0x80" : "=m" (*(char *) addr)
+ : "a" (addr), "m" (*(char *) addr) : "cc" );
                 break;
         }
 }
@@ -395,17 +425,17 @@
  * fast, non-SMP test_and_set_bit routine
  */
 static inline int
-test_and_set_bit_simple(int nr, volatile unsigned long *ptr)
+test_and_set_bit_simple(unsigned long nr, volatile unsigned long *ptr)
 {
         unsigned long addr;
         unsigned char ch;
 
- addr = (unsigned long) ptr + ((nr ^ 24) >> 3);
+ addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
         ch = *(unsigned char *) addr;
         asm volatile("oc 0(1,%1),0(%2)"
- : "+m" (*(char *) addr)
- : "a" (addr), "a" (_oi_bitmap + (nr & 7))
- : "cc" );
+ : "=m" (*(char *) addr)
+ : "a" (addr), "a" (_oi_bitmap + (nr & 7)),
+ "m" (*(char *) addr) : "cc" );
         return (ch >> (nr & 7)) & 1;
 }
 #define __test_and_set_bit(X,Y) test_and_set_bit_simple(X,Y)
@@ -414,17 +444,17 @@
  * fast, non-SMP test_and_clear_bit routine
  */
 static inline int
-test_and_clear_bit_simple(int nr, volatile unsigned long *ptr)
+test_and_clear_bit_simple(unsigned long nr, volatile unsigned long *ptr)
 {
         unsigned long addr;
         unsigned char ch;
 
- addr = (unsigned long) ptr + ((nr ^ 24) >> 3);
+ addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
         ch = *(unsigned char *) addr;
         asm volatile("nc 0(1,%1),0(%2)"
- : "+m" (*(char *) addr)
- : "a" (addr), "a" (_ni_bitmap + (nr & 7))
- : "cc" );
+ : "=m" (*(char *) addr)
+ : "a" (addr), "a" (_ni_bitmap + (nr & 7)),
+ "m" (*(char *) addr) : "cc" );
         return (ch >> (nr & 7)) & 1;
 }
 #define __test_and_clear_bit(X,Y) test_and_clear_bit_simple(X,Y)
@@ -433,17 +463,17 @@
  * fast, non-SMP test_and_change_bit routine
  */
 static inline int
-test_and_change_bit_simple(int nr, volatile unsigned long *ptr)
+test_and_change_bit_simple(unsigned long nr, volatile unsigned long *ptr)
 {
         unsigned long addr;
         unsigned char ch;
 
- addr = (unsigned long) ptr + ((nr ^ 24) >> 3);
+ addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
         ch = *(unsigned char *) addr;
         asm volatile("xc 0(1,%1),0(%2)"
- : "+m" (*(char *) addr)
- : "a" (addr), "a" (_oi_bitmap + (nr & 7))
- : "cc" );
+ : "=m" (*(char *) addr)
+ : "a" (addr), "a" (_oi_bitmap + (nr & 7)),
+ "m" (*(char *) addr) : "cc" );
         return (ch >> (nr & 7)) & 1;
 }
 #define __test_and_change_bit(X,Y) test_and_change_bit_simple(X,Y)
@@ -469,19 +499,20 @@
  * This routine doesn't need to be atomic.
  */
 
-static inline int __test_bit(int nr, const volatile unsigned long *ptr)
+static inline int __test_bit(unsigned long nr, const volatile unsigned long *ptr)
 {
         unsigned long addr;
         unsigned char ch;
 
- addr = (unsigned long) ptr + ((nr ^ 24) >> 3);
+ addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
         ch = *(unsigned char *) addr;
         return (ch >> (nr & 7)) & 1;
 }
 
 static inline int
-__constant_test_bit(int nr, const volatile unsigned long * addr) {
- return (((volatile char *) addr)[(nr>>3)^3] & (1<<(nr&7))) != 0;
+__constant_test_bit(unsigned long nr, const volatile unsigned long *addr) {
+ return (((volatile char *) addr)
+ [(nr^(__BITOPS_WORDSIZE-8))>>3] & (1<<(nr&7)));
 }
 
 #define test_bit(nr,addr) \
@@ -489,6 +520,8 @@
  __constant_test_bit((nr),(addr)) : \
  __test_bit((nr),(addr)) )
 
+#ifndef __s390x__
+
 /*
  * Find-bit routines..
  */
@@ -701,6 +734,245 @@
         return result;
 }
 
+#else /* __s390x__ */
+
+/*
+ * Find-bit routines..
+ */
+static inline unsigned long
+find_first_zero_bit(unsigned long * addr, unsigned long size)
+{
+ unsigned long res, cmp, count;
+
+ if (!size)
+ return 0;
+ __asm__(" lghi %1,-1\n"
+ " lgr %2,%3\n"
+ " slgr %0,%0\n"
+ " aghi %2,63\n"
+ " srlg %2,%2,6\n"
+ "0: cg %1,0(%0,%4)\n"
+ " jne 1f\n"
+ " aghi %0,8\n"
+ " brct %2,0b\n"
+ " lgr %0,%3\n"
+ " j 5f\n"
+ "1: lg %2,0(%0,%4)\n"
+ " sllg %0,%0,3\n"
+ " clr %2,%1\n"
+ " jne 2f\n"
+ " aghi %0,32\n"
+ " srlg %2,%2,32\n"
+ "2: lghi %1,0xff\n"
+ " tmll %2,0xffff\n"
+ " jno 3f\n"
+ " aghi %0,16\n"
+ " srl %2,16\n"
+ "3: tmll %2,0x00ff\n"
+ " jno 4f\n"
+ " aghi %0,8\n"
+ " srl %2,8\n"
+ "4: ngr %2,%1\n"
+ " ic %2,0(%2,%5)\n"
+ " algr %0,%2\n"
+ "5:"
+ : "=&a" (res), "=&d" (cmp), "=&a" (count)
+ : "a" (size), "a" (addr), "a" (&_zb_findmap) : "cc" );
+ return (res < size) ? res : size;
+}
+
+static inline unsigned long
+find_first_bit(unsigned long * addr, unsigned long size)
+{
+ unsigned long res, cmp, count;
+
+ if (!size)
+ return 0;
+ __asm__(" slgr %1,%1\n"
+ " lgr %2,%3\n"
+ " slgr %0,%0\n"
+ " aghi %2,63\n"
+ " srlg %2,%2,6\n"
+ "0: cg %1,0(%0,%4)\n"
+ " jne 1f\n"
+ " aghi %0,8\n"
+ " brct %2,0b\n"
+ " lgr %0,%3\n"
+ " j 5f\n"
+ "1: lg %2,0(%0,%4)\n"
+ " sllg %0,%0,3\n"
+ " clr %2,%1\n"
+ " jne 2f\n"
+ " aghi %0,32\n"
+ " srlg %2,%2,32\n"
+ "2: lghi %1,0xff\n"
+ " tmll %2,0xffff\n"
+ " jnz 3f\n"
+ " aghi %0,16\n"
+ " srl %2,16\n"
+ "3: tmll %2,0x00ff\n"
+ " jnz 4f\n"
+ " aghi %0,8\n"
+ " srl %2,8\n"
+ "4: ngr %2,%1\n"
+ " ic %2,0(%2,%5)\n"
+ " algr %0,%2\n"
+ "5:"
+ : "=&a" (res), "=&d" (cmp), "=&a" (count)
+ : "a" (size), "a" (addr), "a" (&_sb_findmap) : "cc" );
+ return (res < size) ? res : size;
+}
+
+static inline unsigned long
+find_next_zero_bit (unsigned long * addr, unsigned long size, unsigned long offset)
+{
+ unsigned long * p = ((unsigned long *) addr) + (offset >> 6);
+ unsigned long bitvec, reg;
+ unsigned long set, bit = offset & 63, res;
+
+ if (bit) {
+ /*
+ * Look for zero in first word
+ */
+ bitvec = (*p) >> bit;
+ __asm__(" lhi %2,-1\n"
+ " slgr %0,%0\n"
+ " clr %1,%2\n"
+ " jne 0f\n"
+ " aghi %0,32\n"
+ " srlg %1,%1,32\n"
+ "0: lghi %2,0xff\n"
+ " tmll %1,0xffff\n"
+ " jno 1f\n"
+ " aghi %0,16\n"
+ " srlg %1,%1,16\n"
+ "1: tmll %1,0x00ff\n"
+ " jno 2f\n"
+ " aghi %0,8\n"
+ " srlg %1,%1,8\n"
+ "2: ngr %1,%2\n"
+ " ic %1,0(%1,%3)\n"
+ " algr %0,%1"
+ : "=&d" (set), "+a" (bitvec), "=&d" (reg)
+ : "a" (&_zb_findmap) : "cc" );
+ if (set < (64 - bit))
+ return set + offset;
+ offset += 64 - bit;
+ p++;
+ }
+ /*
+ * No zero yet, search remaining full words for a zero
+ */
+ res = find_first_zero_bit (p, size - 64 * (p - (unsigned long *) addr));
+ return (offset + res);
+}
+
+static inline unsigned long
+find_next_bit (unsigned long * addr, unsigned long size, unsigned long offset)
+{
+ unsigned long * p = ((unsigned long *) addr) + (offset >> 6);
+ unsigned long bitvec, reg;
+ unsigned long set, bit = offset & 63, res;
+
+ if (bit) {
+ /*
+ * Look for zero in first word
+ */
+ bitvec = (*p) >> bit;
+ __asm__(" slgr %0,%0\n"
+ " ltr %1,%1\n"
+ " jnz 0f\n"
+ " aghi %0,32\n"
+ " srlg %1,%1,32\n"
+ "0: lghi %2,0xff\n"
+ " tmll %1,0xffff\n"
+ " jnz 1f\n"
+ " aghi %0,16\n"
+ " srlg %1,%1,16\n"
+ "1: tmll %1,0x00ff\n"
+ " jnz 2f\n"
+ " aghi %0,8\n"
+ " srlg %1,%1,8\n"
+ "2: ngr %1,%2\n"
+ " ic %1,0(%1,%3)\n"
+ " algr %0,%1"
+ : "=&d" (set), "+a" (bitvec), "=&d" (reg)
+ : "a" (&_sb_findmap) : "cc" );
+ if (set < (64 - bit))
+ return set + offset;
+ offset += 64 - bit;
+ p++;
+ }
+ /*
+ * No set bit yet, search remaining full words for a bit
+ */
+ res = find_first_bit (p, size - 64 * (p - (unsigned long *) addr));
+ return (offset + res);
+}
+
+/*
+ * ffz = Find First Zero in word. Undefined if no zero exists,
+ * so code should check against ~0UL first..
+ */
+static inline unsigned long ffz(unsigned long word)
+{
+ unsigned long reg, result;
+
+ __asm__(" lhi %2,-1\n"
+ " slgr %0,%0\n"
+ " clr %1,%2\n"
+ " jne 0f\n"
+ " aghi %0,32\n"
+ " srlg %1,%1,32\n"
+ "0: lghi %2,0xff\n"
+ " tmll %1,0xffff\n"
+ " jno 1f\n"
+ " aghi %0,16\n"
+ " srlg %1,%1,16\n"
+ "1: tmll %1,0x00ff\n"
+ " jno 2f\n"
+ " aghi %0,8\n"
+ " srlg %1,%1,8\n"
+ "2: ngr %1,%2\n"
+ " ic %1,0(%1,%3)\n"
+ " algr %0,%1"
+ : "=&d" (result), "+a" (word), "=&d" (reg)
+ : "a" (&_zb_findmap) : "cc" );
+ return result;
+}
+
+/*
+ * __ffs = find first bit in word. Undefined if no bit exists,
+ * so code should check against 0UL first..
+ */
+static inline unsigned long __ffs (unsigned long word)
+{
+ unsigned long reg, result;
+
+ __asm__(" slgr %0,%0\n"
+ " ltr %1,%1\n"
+ " jnz 0f\n"
+ " aghi %0,32\n"
+ " srlg %1,%1,32\n"
+ "0: lghi %2,0xff\n"
+ " tmll %1,0xffff\n"
+ " jnz 1f\n"
+ " aghi %0,16\n"
+ " srlg %1,%1,16\n"
+ "1: tmll %1,0x00ff\n"
+ " jnz 2f\n"
+ " aghi %0,8\n"
+ " srlg %1,%1,8\n"
+ "2: ngr %1,%2\n"
+ " ic %1,0(%1,%3)\n"
+ " algr %0,%1"
+ : "=&d" (result), "+a" (word), "=&d" (reg)
+ : "a" (&_sb_findmap) : "cc" );
+ return result;
+}
+
+#endif /* __s390x__ */
+
 /*
  * Every architecture must define this function. It's the fastest
  * way of searching a 140-bit bitmap where the first 100 bits are
@@ -717,7 +989,6 @@
  * the libc and compiler builtin ffs routines, therefore
  * differs in spirit from the above ffz (man ffs).
  */
-
 extern inline int ffs (int x)
 {
         int r = 1;
@@ -785,7 +1056,14 @@
  * hweightN: returns the hamming weight (i.e. the number
  * of bits set) of a N-bit word
  */
-
+#define hweight64(x) \
+({ \
+ unsigned long __x = (x); \
+ unsigned int __w; \
+ __w = generic_hweight32((unsigned int) __x); \
+ __w += generic_hweight32((unsigned int) (__x>>32)); \
+ __w; \
+})
 #define hweight32(x) generic_hweight32(x)
 #define hweight16(x) generic_hweight16(x)
 #define hweight8(x) generic_hweight8(x)
@@ -804,15 +1082,17 @@
  */
 
 #define ext2_set_bit(nr, addr) \
- test_and_set_bit((nr)^24, (unsigned long *)addr)
+ test_and_set_bit((nr)^(__BITOPS_WORDSIZE - 8), (unsigned long *)addr)
 #define ext2_set_bit_atomic(lock, nr, addr) \
- test_and_set_bit((nr)^24, (unsigned long *)addr)
+ test_and_set_bit((nr)^(__BITOPS_WORDSIZE - 8), (unsigned long *)addr)
 #define ext2_clear_bit(nr, addr) \
- test_and_clear_bit((nr)^24, (unsigned long *)addr)
+ test_and_clear_bit((nr)^(__BITOPS_WORDSIZE - 8), (unsigned long *)addr)
 #define ext2_clear_bit_atomic(lock, nr, addr) \
- test_and_clear_bit((nr)^24, (unsigned long *)addr)
+ test_and_clear_bit((nr)^(__BITOPS_WORDSIZE - 8), (unsigned long *)addr)
 #define ext2_test_bit(nr, addr) \
- test_bit((nr)^24, (unsigned long *)addr)
+ test_bit((nr)^(__BITOPS_WORDSIZE - 8), (unsigned long *)addr)
+
+#ifndef __s390x__
 
 static inline int
 ext2_find_first_zero_bit(void *vaddr, unsigned size)
@@ -897,6 +1177,100 @@
         return (p - addr) * 32 + res;
 }
 
+#else /* __s390x__ */
+
+static inline unsigned long
+ext2_find_first_zero_bit(void *vaddr, unsigned long size)
+{
+ unsigned long res, cmp, count;
+
+ if (!size)
+ return 0;
+ __asm__(" lghi %1,-1\n"
+ " lgr %2,%3\n"
+ " aghi %2,63\n"
+ " srlg %2,%2,6\n"
+ " slgr %0,%0\n"
+ "0: clg %1,0(%0,%4)\n"
+ " jne 1f\n"
+ " aghi %0,8\n"
+ " brct %2,0b\n"
+ " lgr %0,%3\n"
+ " j 5f\n"
+ "1: cl %1,0(%0,%4)\n"
+ " jne 2f\n"
+ " aghi %0,4\n"
+ "2: l %2,0(%0,%4)\n"
+ " sllg %0,%0,3\n"
+ " aghi %0,24\n"
+ " lghi %1,0xff\n"
+ " tmlh %2,0xffff\n"
+ " jo 3f\n"
+ " aghi %0,-16\n"
+ " srl %2,16\n"
+ "3: tmll %2,0xff00\n"
+ " jo 4f\n"
+ " aghi %0,-8\n"
+ " srl %2,8\n"
+ "4: ngr %2,%1\n"
+ " ic %2,0(%2,%5)\n"
+ " algr %0,%2\n"
+ "5:"
+ : "=&a" (res), "=&d" (cmp), "=&a" (count)
+ : "a" (size), "a" (vaddr), "a" (&_zb_findmap) : "cc" );
+ return (res < size) ? res : size;
+}
+
+static inline unsigned long
+ext2_find_next_zero_bit(void *vaddr, unsigned long size, unsigned long offset)
+{
+ unsigned long *addr = vaddr;
+ unsigned long *p = addr + (offset >> 6);
+ unsigned long word, reg;
+ unsigned long bit = offset & 63UL, res;
+
+ if (offset >= size)
+ return size;
+
+ if (bit) {
+ __asm__(" lrvg %0,%1" /* load reversed, neat instruction */
+ : "=a" (word) : "m" (*p) );
+ word >>= bit;
+ res = bit;
+ /* Look for zero in first 8 byte word */
+ __asm__(" lghi %2,0xff\n"
+ " tmll %1,0xffff\n"
+ " jno 2f\n"
+ " ahi %0,16\n"
+ " srlg %1,%1,16\n"
+ "0: tmll %1,0xffff\n"
+ " jno 2f\n"
+ " ahi %0,16\n"
+ " srlg %1,%1,16\n"
+ "1: tmll %1,0xffff\n"
+ " jno 2f\n"
+ " ahi %0,16\n"
+ " srl %1,16\n"
+ "2: tmll %1,0x00ff\n"
+ " jno 3f\n"
+ " ahi %0,8\n"
+ " srl %1,8\n"
+ "3: ngr %1,%2\n"
+ " ic %1,0(%1,%3)\n"
+ " alr %0,%1"
+ : "+&d" (res), "+a" (word), "=&d" (reg)
+ : "a" (&_zb_findmap) : "cc" );
+ if (res < 64)
+ return (p - addr)*64 + res;
+ p++;
+ }
+ /* No zero yet, search remaining full bytes for a zero */
+ res = ext2_find_first_zero_bit (p, size - 64 * (p - addr));
+ return (p - addr) * 64 + res;
+}
+
+#endif /* __s390x__ */
+
 /* Bitmap functions for the minix filesystem. */
 /* FIXME !!! */
 #define minix_test_and_set_bit(nr,addr) test_and_set_bit(nr,addr)
diff -urN linux-2.5.67/include/asm-s390/byteorder.h linux-2.5.67-s390/include/asm-s390/byteorder.h
--- linux-2.5.67/include/asm-s390/byteorder.h Mon Apr 7 19:33:01 2003
+++ linux-2.5.67-s390/include/asm-s390/byteorder.h Mon Apr 14 19:11:58 2003
@@ -13,22 +13,63 @@
 
 #ifdef __GNUC__
 
+#ifdef __s390x__
+static __inline__ __const__ __u64 ___arch__swab64p(__u64 *x)
+{
+ __u64 result;
+
+ __asm__ __volatile__ (
+ " lrvg %0,%1"
+ : "=d" (result) : "m" (*x) );
+ return result;
+}
+
+static __inline__ __const__ __u64 ___arch__swab64(__u64 x)
+{
+ __u64 result;
+
+ __asm__ __volatile__ (
+ " lrvgr %0,%1"
+ : "=d" (result) : "d" (x) );
+ return result;
+}
+
+static __inline__ void ___arch__swab64s(__u64 *x)
+{
+ *x = ___arch__swab64p(x);
+}
+#endif /* __s390x__ */
+
 static __inline__ __const__ __u32 ___arch__swab32p(__u32 *x)
 {
         __u32 result;
         
         __asm__ __volatile__ (
+#ifndef __s390x__
                 " icm %0,8,3(%1)\n"
                 " icm %0,4,2(%1)\n"
                 " icm %0,2,1(%1)\n"
                 " ic %0,0(%1)"
                 : "=&d" (result) : "a" (x) : "cc" );
+#else /* __s390x__ */
+ " lrv %0,%1"
+ : "=d" (result) : "m" (*x) );
+#endif /* __s390x__ */
         return result;
 }
 
 static __inline__ __const__ __u32 ___arch__swab32(__u32 x)
 {
+#ifndef __s390x__
         return ___arch__swab32p(&x);
+#else /* __s390x__ */
+ __u32 result;
+
+ __asm__ __volatile__ (
+ " lrvr %0,%1"
+ : "=d" (result) : "d" (x) );
+ return result;
+#endif /* __s390x__ */
 }
 
 static __inline__ void ___arch__swab32s(__u32 *x)
@@ -41,9 +82,14 @@
         __u16 result;
         
         __asm__ __volatile__ (
+#ifndef __s390x__
                 " icm %0,2,1(%1)\n"
                 " ic %0,0(%1)\n"
                 : "=&d" (result) : "a" (x) : "cc" );
+#else /* __s390x__ */
+ " lrvh %0,%1"
+ : "=d" (result) : "m" (*x) );
+#endif /* __s390x__ */
         return result;
 }
 
@@ -57,6 +103,11 @@
         *x = ___arch__swab16p(x);
 }
 
+#ifdef __s390x__
+#define __arch__swab64(x) ___arch__swab64(x)
+#define __arch__swab64p(x) ___arch__swab64p(x)
+#define __arch__swab64s(x) ___arch__swab64s(x)
+#endif /* __s390x__ */
 #define __arch__swab32(x) ___arch__swab32(x)
 #define __arch__swab16(x) ___arch__swab16(x)
 #define __arch__swab32p(x) ___arch__swab32p(x)
@@ -64,10 +115,14 @@
 #define __arch__swab32s(x) ___arch__swab32s(x)
 #define __arch__swab16s(x) ___arch__swab16s(x)
 
+#ifndef __s390x__
 #if !defined(__STRICT_ANSI__) || defined(__KERNEL__)
 # define __BYTEORDER_HAS_U64__
 # define __SWAB_64_THRU_32__
 #endif
+#else /* __s390x__ */
+#define __BYTEORDER_HAS_U64__
+#endif /* __s390x__ */
 
 #endif /* __GNUC__ */
 
diff -urN linux-2.5.67/include/asm-s390/ccwdev.h linux-2.5.67-s390/include/asm-s390/ccwdev.h
--- linux-2.5.67/include/asm-s390/ccwdev.h Mon Apr 7 19:32:27 2003
+++ linux-2.5.67-s390/include/asm-s390/ccwdev.h Mon Apr 14 19:11:58 2003
@@ -157,6 +157,16 @@
  */
 extern int ccw_device_start(struct ccw_device *, struct ccw1 *,
                             unsigned long, __u8, unsigned long);
+/*
+ * ccw_device_start_timeout()
+ *
+ * This function notifies the device driver if the channel program has not
+ * completed during the specified time. If a timeout occurs, the channel
+ * program is terminated via xsch(), hsch() or csch().
+ */
+extern int ccw_device_start_timeout(struct ccw_device *, struct ccw1 *,
+ unsigned long, __u8, unsigned long, int);
+
 extern int ccw_device_resume(struct ccw_device *);
 extern int ccw_device_halt(struct ccw_device *, unsigned long);
 extern int ccw_device_clear(struct ccw_device *, unsigned long);
diff -urN linux-2.5.67/include/asm-s390/checksum.h linux-2.5.67-s390/include/asm-s390/checksum.h
--- linux-2.5.67/include/asm-s390/checksum.h Mon Apr 7 19:30:34 2003
+++ linux-2.5.67-s390/include/asm-s390/checksum.h Mon Apr 14 19:11:58 2003
@@ -30,17 +30,29 @@
 static inline unsigned int
 csum_partial(const unsigned char * buff, int len, unsigned int sum)
 {
- register_pair rp;
         /*
          * Experiments with ethernet and slip connections show that buf
          * is aligned on either a 2-byte or 4-byte boundary.
          */
+#ifndef __s390x__
+ register_pair rp;
+
         rp.subreg.even = (unsigned long) buff;
         rp.subreg.odd = (unsigned long) len;
         __asm__ __volatile__ (
                 "0: cksm %0,%1\n" /* do checksum on longs */
                 " jo 0b\n"
                 : "+&d" (sum), "+&a" (rp) : : "cc" );
+#else /* __s390x__ */
+ __asm__ __volatile__ (
+ " lgr 2,%1\n" /* address in gpr 2 */
+ " lgfr 3,%2\n" /* length in gpr 3 */
+ "0: cksm %0,2\n" /* do checksum on longs */
+ " jo 0b\n"
+ : "+&d" (sum)
+ : "d" (buff), "d" (len)
+ : "cc", "2", "3" );
+#endif /* __s390x__ */
         return sum;
 }
 
@@ -50,6 +62,7 @@
 static inline unsigned int
 csum_partial_inline(const unsigned char * buff, int len, unsigned int sum)
 {
+#ifndef __s390x__
         register_pair rp;
 
         rp.subreg.even = (unsigned long) buff;
@@ -58,6 +71,16 @@
                 "0: cksm %0,%1\n" /* do checksum on longs */
                 " jo 0b\n"
                 : "+&d" (sum), "+&a" (rp) : : "cc" );
+#else /* __s390x__ */
+ __asm__ __volatile__ (
+ " lgr 2,%1\n" /* address in gpr 2 */
+ " lgfr 3,%2\n" /* length in gpr 3 */
+ "0: cksm %0,2\n" /* do checksum on longs */
+ " jo 0b\n"
+ : "+&d" (sum)
+ : "d" (buff), "d" (len)
+ : "cc", "2", "3" );
+#endif /* __s390x__ */
         return sum;
 }
 
@@ -100,6 +123,7 @@
 static inline unsigned short
 csum_fold(unsigned int sum)
 {
+#ifndef __s390x__
         register_pair rp;
 
         __asm__ __volatile__ (
@@ -110,6 +134,16 @@
                 " alr %0,%1\n" /* %0 = H+L+C L+H */
                 " srl %0,16\n" /* %0 = H+L+C */
                 : "+&d" (sum), "=d" (rp) : : "cc" );
+#else /* __s390x__ */
+ __asm__ __volatile__ (
+ " sr 3,3\n" /* %0 = H*65536 + L */
+ " lr 2,%0\n" /* %0 = H L, R2/R3 = H L / 0 0 */
+ " srdl 2,16\n" /* %0 = H L, R2/R3 = 0 H / L 0 */
+ " alr 2,3\n" /* %0 = H L, R2/R3 = L H / L 0 */
+ " alr %0,2\n" /* %0 = H+L+C L+H */
+ " srl %0,16\n" /* %0 = H+L+C */
+ : "+&d" (sum) : : "cc", "2", "3");
+#endif /* __s390x__ */
         return ((unsigned short) ~sum);
 }
 
@@ -121,8 +155,9 @@
 static inline unsigned short
 ip_fast_csum(unsigned char *iph, unsigned int ihl)
 {
- register_pair rp;
         unsigned long sum;
+#ifndef __s390x__
+ register_pair rp;
 
         rp.subreg.even = (unsigned long) iph;
         rp.subreg.odd = (unsigned long) ihl*4;
@@ -131,6 +166,17 @@
                 "0: cksm %0,%1\n" /* do checksum on longs */
                 " jo 0b\n"
                 : "=&d" (sum), "+&a" (rp) : : "cc" );
+#else /* __s390x__ */
+ __asm__ __volatile__ (
+ " slgr %0,%0\n" /* set sum to zero */
+ " lgr 2,%1\n" /* address in gpr 2 */
+ " lgfr 3,%2\n" /* length in gpr 3 */
+ "0: cksm %0,2\n" /* do checksum on ints */
+ " jo 0b\n"
+ : "=&d" (sum)
+ : "d" (iph), "d" (ihl*4)
+ : "cc", "2", "3" );
+#endif /* __s390x__ */
         return csum_fold(sum);
 }
 
@@ -143,6 +189,7 @@
                    unsigned short len, unsigned short proto,
                    unsigned int sum)
 {
+#ifndef __s390x__
         __asm__ __volatile__ (
                 " alr %0,%1\n" /* sum += saddr */
                 " brc 12,0f\n"
@@ -163,6 +210,28 @@
                 : "+&d" (sum)
                 : "d" (((unsigned int) len<<16) + (unsigned int) proto)
                 : "cc" );
+#else /* __s390x__ */
+ __asm__ __volatile__ (
+ " lgfr %0,%0\n"
+ " algr %0,%1\n" /* sum += saddr */
+ " brc 12,0f\n"
+ " aghi %0,1\n" /* add carry */
+ "0: algr %0,%2\n" /* sum += daddr */
+ " brc 12,1f\n"
+ " aghi %0,1\n" /* add carry */
+ "1: algfr %0,%3\n" /* sum += (len<<16) + proto */
+ " brc 12,2f\n"
+ " aghi %0,1\n" /* add carry */
+ "2: srlg 0,%0,32\n"
+ " alr %0,0\n" /* fold to 32 bits */
+ " brc 12,3f\n"
+ " ahi %0,1\n" /* add carry */
+ "3: llgfr %0,%0"
+ : "+&d" (sum)
+ : "d" (saddr), "d" (daddr),
+ "d" (((unsigned int) len<<16) + (unsigned int) proto)
+ : "cc", "0" );
+#endif /* __s390x__ */
         return sum;
 }
 
diff -urN linux-2.5.67/include/asm-s390/compat.h linux-2.5.67-s390/include/asm-s390/compat.h
--- linux-2.5.67/include/asm-s390/compat.h Thu Jan 1 01:00:00 1970
+++ linux-2.5.67-s390/include/asm-s390/compat.h Mon Apr 14 19:11:58 2003
@@ -0,0 +1,122 @@
+#ifndef _ASM_S390X_COMPAT_H
+#define _ASM_S390X_COMPAT_H
+/*
+ * Architecture specific compatibility types
+ */
+#include <linux/types.h>
+
+#define COMPAT_USER_HZ 100
+
+typedef u32 compat_size_t;
+typedef s32 compat_ssize_t;
+typedef s32 compat_time_t;
+typedef s32 compat_clock_t;
+typedef s32 compat_pid_t;
+typedef u16 compat_uid_t;
+typedef u16 compat_gid_t;
+typedef u16 compat_mode_t;
+typedef u32 compat_ino_t;
+typedef u16 compat_dev_t;
+typedef s32 compat_off_t;
+typedef s64 compat_loff_t;
+typedef u16 compat_nlink_t;
+typedef u16 compat_ipc_pid_t;
+typedef s32 compat_daddr_t;
+typedef u32 compat_caddr_t;
+typedef __kernel_fsid_t compat_fsid_t;
+
+typedef s32 compat_int_t;
+typedef s32 compat_long_t;
+typedef u32 compat_uint_t;
+typedef u32 compat_ulong_t;
+
+struct compat_timespec {
+ compat_time_t tv_sec;
+ s32 tv_nsec;
+};
+
+struct compat_timeval {
+ compat_time_t tv_sec;
+ s32 tv_usec;
+};
+
+struct compat_stat {
+ compat_dev_t st_dev;
+ u16 __pad1;
+ compat_ino_t st_ino;
+ compat_mode_t st_mode;
+ compat_nlink_t st_nlink;
+ compat_uid_t st_uid;
+ compat_gid_t st_gid;
+ compat_dev_t st_rdev;
+ u16 __pad2;
+ u32 st_size;
+ u32 st_blksize;
+ u32 st_blocks;
+ u32 st_atime;
+ u32 st_atime_nsec;
+ u32 st_mtime;
+ u32 st_mtime_nsec;
+ u32 st_ctime;
+ u32 st_ctime_nsec;
+ u32 __unused4;
+ u32 __unused5;
+};
+
+struct compat_flock {
+ short l_type;
+ short l_whence;
+ compat_off_t l_start;
+ compat_off_t l_len;
+ compat_pid_t l_pid;
+};
+
+#define F_GETLK64 12
+#define F_SETLK64 13
+#define F_SETLKW64 14
+
+struct compat_flock64 {
+ short l_type;
+ short l_whence;
+ compat_loff_t l_start;
+ compat_loff_t l_len;
+ compat_pid_t l_pid;
+};
+
+struct compat_statfs {
+ s32 f_type;
+ s32 f_bsize;
+ s32 f_blocks;
+ s32 f_bfree;
+ s32 f_bavail;
+ s32 f_files;
+ s32 f_ffree;
+ compat_fsid_t f_fsid;
+ s32 f_namelen;
+ s32 f_spare[6];
+};
+
+typedef u32 compat_old_sigset_t; /* at least 32 bits */
+
+#define _COMPAT_NSIG 64
+#define _COMPAT_NSIG_BPW 32
+
+typedef u32 compat_sigset_word;
+
+#define COMPAT_OFF_T_MAX 0x7fffffff
+#define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL
+
+/*
+ * A pointer passed in from user mode. This should not
+ * be used for syscall parameters, just declare them
+ * as pointers because the syscall entry code will have
+ * appropriately comverted them already.
+ */
+typedef u32 compat_uptr_t;
+
+static inline void *compat_ptr(compat_uptr_t uptr)
+{
+ return (void *)(unsigned long)(uptr & 0x7fffffffUL);
+}
+
+#endif /* _ASM_S390X_COMPAT_H */
diff -urN linux-2.5.67/include/asm-s390/div64.h linux-2.5.67-s390/include/asm-s390/div64.h
--- linux-2.5.67/include/asm-s390/div64.h Mon Apr 7 19:31:55 2003
+++ linux-2.5.67-s390/include/asm-s390/div64.h Mon Apr 14 19:11:58 2003
@@ -1,8 +1,9 @@
 #ifndef __S390_DIV64
 #define __S390_DIV64
 
+#ifndef __s390x__
+
 /* for do_div "base" needs to be smaller than 2^31-1 */
-
 #define do_div(n, base) ({ \
         unsigned long long __n = (n); \
         unsigned long __r; \
@@ -41,4 +42,14 @@
         __r; \
 })
 
+#else /* __s390x__ */
+
+#define do_div(n,base) ({ \
+int __res; \
+__res = ((unsigned long) n) % (unsigned) base; \
+n = ((unsigned long) n) / (unsigned) base; \
+__res; })
+
+#endif /* __s390x__ */
+
 #endif
diff -urN linux-2.5.67/include/asm-s390/ebcdic.h linux-2.5.67-s390/include/asm-s390/ebcdic.h
--- linux-2.5.67/include/asm-s390/ebcdic.h Mon Apr 7 19:31:09 2003
+++ linux-2.5.67-s390/include/asm-s390/ebcdic.h Mon Apr 14 19:11:58 2003
@@ -21,8 +21,8 @@
 extern __u8 _ebc_tolower[]; /* EBCDIC -> lowercase */
 extern __u8 _ebc_toupper[]; /* EBCDIC -> uppercase */
 
-extern __inline__
-void codepage_convert(const __u8 *codepage, volatile __u8 * addr, int nr)
+extern __inline__ void
+codepage_convert(const __u8 *codepage, volatile __u8 * addr, unsigned long nr)
 {
         if (nr-- <= 0)
                 return;
diff -urN linux-2.5.67/include/asm-s390/elf.h linux-2.5.67-s390/include/asm-s390/elf.h
--- linux-2.5.67/include/asm-s390/elf.h Mon Apr 7 19:32:48 2003
+++ linux-2.5.67-s390/include/asm-s390/elf.h Mon Apr 14 19:11:58 2003
@@ -23,7 +23,11 @@
 /*
  * These are used to set parameters in the core dumps.
  */
+#ifndef __s390x__
 #define ELF_CLASS ELFCLASS32
+#else /* __s390x__ */
+#define ELF_CLASS ELFCLASS64
+#endif /* __s390x__ */
 #define ELF_DATA ELFDATA2MSB
 #define ELF_ARCH EM_S390
 
@@ -36,8 +40,16 @@
 
 /* For SVR4/S390 the function pointer to be registered with `atexit` is
    passed in R14. */
+#ifndef __s390x__
 #define ELF_PLAT_INIT(_r, load_addr) \
         _r->gprs[14] = 0
+#else /* __s390x__ */
+#define ELF_PLAT_INIT(_r, load_addr) \
+ do { \
+ _r->gprs[14] = 0; \
+ clear_thread_flag(TIF_31BIT); \
+ } while(0)
+#endif /* __s390x__ */
 
 #define USE_ELF_CORE_DUMP
 #define ELF_EXEC_PAGESIZE 4096
@@ -47,9 +59,13 @@
    the loader. We need to make sure that it is out of the way of the program
    that it will "exec", and that there is sufficient room for the brk. */
 
+#ifndef __s390x__
 #define ELF_ET_DYN_BASE ((TASK_SIZE & 0x80000000) \
                                 ? TASK_SIZE / 3 * 2 \
                                 : 2 * TASK_SIZE / 3)
+#else /* __s390x__ */
+#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
+#endif /* __s390x__ */
 
 /* Wow, the "main" arch needs arch dependent functions too.. :) */
 
@@ -76,7 +92,18 @@
 #define ELF_PLATFORM (NULL)
 
 #ifdef __KERNEL__
+#ifndef __s390x__
 #define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
+#else /* __s390x__ */
+#define SET_PERSONALITY(ex, ibcs2) \
+do { \
+ if (ibcs2) \
+ set_personality(PER_SVR4); \
+ else if (current->personality != PER_LINUX32) \
+ set_personality(PER_LINUX); \
+ clear_thread_flag(TIF_31BIT); \
+} while (0)
+#endif /* __s390x__ */
 #endif
 
 #endif
diff -urN linux-2.5.67/include/asm-s390/fcntl.h linux-2.5.67-s390/include/asm-s390/fcntl.h
--- linux-2.5.67/include/asm-s390/fcntl.h Mon Apr 7 19:30:33 2003
+++ linux-2.5.67-s390/include/asm-s390/fcntl.h Mon Apr 14 19:11:58 2003
@@ -42,10 +42,11 @@
 #define F_SETSIG 10 /* for sockets. */
 #define F_GETSIG 11 /* for sockets. */
 
+#ifndef __s390x__
 #define F_GETLK64 12 /* using 'struct flock64' */
 #define F_SETLK64 13
 #define F_SETLKW64 14
-
+#endif /* ! __s390x__ */
 
 /* for F_[GET|SET]FL */
 #define FD_CLOEXEC 1 /* actually anything with low bit set goes */
@@ -82,6 +83,7 @@
         pid_t l_pid;
 };
 
+#ifndef __s390x__
 struct flock64 {
         short l_type;
         short l_whence;
@@ -89,6 +91,6 @@
         loff_t l_len;
         pid_t l_pid;
 };
-
+#endif
 #define F_LINUX_SPECIFIC_BASE 1024
 #endif
diff -urN linux-2.5.67/include/asm-s390/gdb-stub.h linux-2.5.67-s390/include/asm-s390/gdb-stub.h
--- linux-2.5.67/include/asm-s390/gdb-stub.h Mon Apr 7 19:31:56 2003
+++ linux-2.5.67-s390/include/asm-s390/gdb-stub.h Thu Jan 1 01:00:00 1970
@@ -1,22 +0,0 @@
-/*
- * include/asm-s390/gdb-stub.h
- *
- * S390 version
- * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
- * Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
- */
-
-#ifndef __S390_GDB_STUB__
-#define __S390_GDB_STUB__
-#include <linux/config.h>
-#if CONFIG_REMOTE_DEBUG
-#include <asm/ptrace.h>
-extern int gdb_stub_initialised;
-extern void gdb_stub_handle_exception(struct gdb_pt_regs *regs,int sigval);
-struct net_device;
-extern struct net_device *gdb_dev;
-void gdb_do_timers(void);
-extern int putDebugChar(char c); /* write a single character */
-extern char getDebugChar(void); /* read and return a single char */
-#endif
-#endif
diff -urN linux-2.5.67/include/asm-s390/idals.h linux-2.5.67-s390/include/asm-s390/idals.h
--- linux-2.5.67/include/asm-s390/idals.h Mon Apr 7 19:30:40 2003
+++ linux-2.5.67-s390/include/asm-s390/idals.h Mon Apr 14 19:11:58 2003
@@ -21,7 +21,7 @@
 #include <asm/cio.h>
 #include <asm/uaccess.h>
 
-#ifdef CONFIG_ARCH_S390X
+#ifdef __s390x__
 #define IDA_SIZE_LOG 12 /* 11 for 2k , 12 for 4k */
 #else
 #define IDA_SIZE_LOG 11 /* 11 for 2k , 12 for 4k */
@@ -34,7 +34,7 @@
 static inline int
 idal_is_needed(void *vaddr, unsigned int length)
 {
-#if defined(CONFIG_ARCH_S390X)
+#ifdef __s390x__
         return ((__pa(vaddr) + length) >> 31) != 0;
 #else
         return 0;
@@ -48,7 +48,7 @@
 static inline unsigned int
 idal_nr_words(void *vaddr, unsigned int length)
 {
-#if defined(CONFIG_ARCH_S390X)
+#ifdef __s390x__
         if (idal_is_needed(vaddr, length))
                 return ((__pa(vaddr) & (IDA_BLOCK_SIZE-1)) + length +
                         (IDA_BLOCK_SIZE-1)) >> IDA_SIZE_LOG;
@@ -62,7 +62,7 @@
 static inline unsigned long *
 idal_create_words(unsigned long *idaws, void *vaddr, unsigned int length)
 {
-#if defined(CONFIG_ARCH_S390X)
+#ifdef __s390x__
         unsigned long paddr;
         unsigned int cidaw;
 
@@ -86,7 +86,7 @@
 static inline int
 set_normalized_cda(struct ccw1 * ccw, void *vaddr)
 {
-#if defined (CONFIG_ARCH_S390X)
+#ifdef __s390x__
         unsigned int nridaws;
         unsigned long *idal;
 
@@ -113,7 +113,7 @@
 static inline void
 clear_normalized_cda(struct ccw1 * ccw)
 {
-#if defined(CONFIG_ARCH_S390X)
+#ifdef __s390x__
         if (ccw->flags & CCW_FLAG_IDA) {
                 kfree((void *)(unsigned long) ccw->cda);
                 ccw->flags &= ~CCW_FLAG_IDA;
@@ -190,7 +190,7 @@
 static inline int
 __idal_buffer_is_needed(struct idal_buffer *ib)
 {
-#ifdef CONFIG_ARCH_S390X
+#ifdef __s390x__
         return ib->size > (4096ul << ib->page_order) ||
                 idal_is_needed(ib->data[0], ib->size);
 #else
diff -urN linux-2.5.67/include/asm-s390/io.h linux-2.5.67-s390/include/asm-s390/io.h
--- linux-2.5.67/include/asm-s390/io.h Mon Apr 7 19:31:56 2003
+++ linux-2.5.67-s390/include/asm-s390/io.h Mon Apr 14 19:11:58 2003
@@ -27,9 +27,16 @@
 extern inline unsigned long virt_to_phys(volatile void * address)
 {
         unsigned long real_address;
- __asm__ (" lra %0,0(%1)\n"
+ __asm__ (
+#ifndef __s390x__
+ " lra %0,0(%1)\n"
                  " jz 0f\n"
                  " sr %0,%0\n"
+#else /* __s390x__ */
+ " lrag %0,0(%1)\n"
+ " jz 0f\n"
+ " slgr %0,%0\n"
+#endif /* __s390x__ */
                  "0:"
                  : "=a" (real_address) : "a" (address) : "cc" );
         return real_address;
diff -urN linux-2.5.67/include/asm-s390/ipc.h linux-2.5.67-s390/include/asm-s390/ipc.h
--- linux-2.5.67/include/asm-s390/ipc.h Mon Apr 7 19:32:54 2003
+++ linux-2.5.67-s390/include/asm-s390/ipc.h Mon Apr 14 19:11:58 2003
@@ -22,6 +22,7 @@
 #define SEMOP 1
 #define SEMGET 2
 #define SEMCTL 3
+#define SEMTIMEDOP 4
 #define MSGSND 11
 #define MSGRCV 12
 #define MSGGET 13
diff -urN linux-2.5.67/include/asm-s390/ipcbuf.h linux-2.5.67-s390/include/asm-s390/ipcbuf.h
--- linux-2.5.67/include/asm-s390/ipcbuf.h Mon Apr 7 19:31:15 2003
+++ linux-2.5.67-s390/include/asm-s390/ipcbuf.h Mon Apr 14 19:11:58 2003
@@ -21,7 +21,9 @@
         __kernel_mode_t mode;
         unsigned short __pad1;
         unsigned short seq;
+#ifndef __s390x__
         unsigned short __pad2;
+#endif /* ! __s390x__ */
         unsigned long __unused1;
         unsigned long __unused2;
 };
diff -urN linux-2.5.67/include/asm-s390/lowcore.h linux-2.5.67-s390/include/asm-s390/lowcore.h
--- linux-2.5.67/include/asm-s390/lowcore.h Mon Apr 7 19:31:19 2003
+++ linux-2.5.67-s390/include/asm-s390/lowcore.h Mon Apr 14 19:11:58 2003
@@ -11,6 +11,7 @@
 #ifndef _ASM_S390_LOWCORE_H
 #define _ASM_S390_LOWCORE_H
 
+#ifndef __s390x__
 #define __LC_EXT_OLD_PSW 0x018
 #define __LC_SVC_OLD_PSW 0x020
 #define __LC_PGM_OLD_PSW 0x028
@@ -21,43 +22,76 @@
 #define __LC_PGM_NEW_PSW 0x068
 #define __LC_MCK_NEW_PSW 0x070
 #define __LC_IO_NEW_PSW 0x078
+#else /* !__s390x__ */
+#define __LC_EXT_OLD_PSW 0x0130
+#define __LC_SVC_OLD_PSW 0x0140
+#define __LC_PGM_OLD_PSW 0x0150
+#define __LC_MCK_OLD_PSW 0x0160
+#define __LC_IO_OLD_PSW 0x0170
+#define __LC_EXT_NEW_PSW 0x01b0
+#define __LC_SVC_NEW_PSW 0x01c0
+#define __LC_PGM_NEW_PSW 0x01d0
+#define __LC_MCK_NEW_PSW 0x01e0
+#define __LC_IO_NEW_PSW 0x01f0
+#endif /* !__s390x__ */
+
 #define __LC_EXT_PARAMS 0x080
 #define __LC_CPU_ADDRESS 0x084
 #define __LC_EXT_INT_CODE 0x086
-#define __LC_SVC_INT_CODE 0x08B
+
+#define __LC_SVC_ILC 0x088
+#define __LC_SVC_INT_CODE 0x08A
 #define __LC_PGM_ILC 0x08C
 #define __LC_PGM_INT_CODE 0x08E
-#define __LC_TRANS_EXC_ADDR 0x090
+
 #define __LC_SUBCHANNEL_ID 0x0B8
 #define __LC_SUBCHANNEL_NR 0x0BA
 #define __LC_IO_INT_PARM 0x0BC
 #define __LC_IO_INT_WORD 0x0C0
 #define __LC_MCCK_CODE 0x0E8
-#define __LC_AREGS_SAVE_AREA 0x120
-#define __LC_CREGS_SAVE_AREA 0x1C0
 
 #define __LC_RETURN_PSW 0x200
-#define __LC_IRB 0x208
+
+#define __LC_IRB 0x210
+
+#define __LC_DIAG44_OPCODE 0x250
 
 #define __LC_SAVE_AREA 0xC00
+
+#ifndef __s390x__
 #define __LC_KERNEL_STACK 0xC40
 #define __LC_ASYNC_STACK 0xC44
 #define __LC_CPUID 0xC60
 #define __LC_CPUADDR 0xC68
 #define __LC_IPLDEV 0xC7C
-
 #define __LC_JIFFY_TIMER 0xC80
+#else /* __s390x__ */
+#define __LC_KERNEL_STACK 0xD40
+#define __LC_ASYNC_STACK 0xD48
+#define __LC_CPUID 0xD90
+#define __LC_CPUADDR 0xD98
+#define __LC_IPLDEV 0xDB8
+#define __LC_JIFFY_TIMER 0xDC0
+#endif /* __s390x__ */
 
 #define __LC_PANIC_MAGIC 0xE00
 
+#ifndef __s390x__
 #define __LC_PFAULT_INTPARM 0x080
+#define __LC_AREGS_SAVE_AREA 0x120
+#define __LC_CREGS_SAVE_AREA 0x1C0
+#else /* __s390x__ */
+#define __LC_PFAULT_INTPARM 0x11B8
+#define __LC_AREGS_SAVE_AREA 0x1340
+#define __LC_CREGS_SAVE_AREA 0x1380
+#endif /* __s390x__ */
 
 #ifndef __ASSEMBLY__
 
 #include <linux/config.h>
+#include <asm/processor.h>
 #include <linux/types.h>
 #include <asm/atomic.h>
-#include <asm/processor.h>
 #include <asm/sigp.h>
 
 void restart_int_handler(void);
@@ -69,6 +103,7 @@
 
 struct _lowcore
 {
+#ifndef __s390x__
         /* prefix area: defined by architecture */
         psw_t restart_psw; /* 0x000 */
         __u32 ccw2[4]; /* 0x008 */
@@ -142,6 +177,101 @@
 
         /* Align to the top 1k of prefix area */
         __u8 pad12[0x1000-0xe04]; /* 0xe04 */
+#else /* !__s390x__ */
+ /* prefix area: defined by architecture */
+ __u32 ccw1[2]; /* 0x000 */
+ __u32 ccw2[4]; /* 0x008 */
+ __u8 pad1[0x80-0x18]; /* 0x018 */
+ __u32 ext_params; /* 0x080 */
+ __u16 cpu_addr; /* 0x084 */
+ __u16 ext_int_code; /* 0x086 */
+ __u16 svc_ilc; /* 0x088 */
+ __u16 svc_code; /* 0x08a */
+ __u16 pgm_ilc; /* 0x08c */
+ __u16 pgm_code; /* 0x08e */
+ __u32 data_exc_code; /* 0x090 */
+ __u16 mon_class_num; /* 0x094 */
+ __u16 per_perc_atmid; /* 0x096 */
+ addr_t per_address; /* 0x098 */
+ __u8 exc_access_id; /* 0x0a0 */
+ __u8 per_access_id; /* 0x0a1 */
+ __u8 op_access_id; /* 0x0a2 */
+ __u8 ar_access_id; /* 0x0a3 */
+ __u8 pad2[0xA8-0xA4]; /* 0x0a4 */
+ addr_t trans_exc_code; /* 0x0A0 */
+ addr_t monitor_code; /* 0x09c */
+ __u16 subchannel_id; /* 0x0b8 */
+ __u16 subchannel_nr; /* 0x0ba */
+ __u32 io_int_parm; /* 0x0bc */
+ __u32 io_int_word; /* 0x0c0 */
+ __u8 pad3[0xc8-0xc4]; /* 0x0c4 */
+ __u32 stfl_fac_list; /* 0x0c8 */
+ __u8 pad4[0xe8-0xcc]; /* 0x0cc */
+ __u32 mcck_interruption_code[2]; /* 0x0e8 */
+ __u8 pad5[0xf4-0xf0]; /* 0x0f0 */
+ __u32 external_damage_code; /* 0x0f4 */
+ addr_t failing_storage_address; /* 0x0f8 */
+ __u8 pad6[0x120-0x100]; /* 0x100 */
+ psw_t restart_old_psw; /* 0x120 */
+ psw_t external_old_psw; /* 0x130 */
+ psw_t svc_old_psw; /* 0x140 */
+ psw_t program_old_psw; /* 0x150 */
+ psw_t mcck_old_psw; /* 0x160 */
+ psw_t io_old_psw; /* 0x170 */
+ __u8 pad7[0x1a0-0x180]; /* 0x180 */
+ psw_t restart_psw; /* 0x1a0 */
+ psw_t external_new_psw; /* 0x1b0 */
+ psw_t svc_new_psw; /* 0x1c0 */
+ psw_t program_new_psw; /* 0x1d0 */
+ psw_t mcck_new_psw; /* 0x1e0 */
+ psw_t io_new_psw; /* 0x1f0 */
+ psw_t return_psw; /* 0x200 */
+ __u8 irb[64]; /* 0x210 */
+ __u32 diag44_opcode; /* 0x250 */
+ __u8 pad8[0xc00-0x254]; /* 0x254 */
+ /* System info area */
+ __u64 save_area[16]; /* 0xc00 */
+ __u8 pad9[0xd40-0xc80]; /* 0xc80 */
+ __u64 kernel_stack; /* 0xd40 */
+ __u64 async_stack; /* 0xd48 */
+ /* entry.S sensitive area start */
+ __u8 pad10[0xd80-0xd50]; /* 0xd64 */
+ struct cpuinfo_S390 cpu_data; /* 0xd80 */
+ __u32 ipl_device; /* 0xdb8 */
+ __u32 pad11; /* 0xdbc */
+ /* entry.S sensitive area end */
+
+ /* SMP info area: defined by DJB */
+ __u64 jiffy_timer; /* 0xdc0 */
+ __u64 ext_call_fast; /* 0xdc8 */
+ __u8 pad12[0xe00-0xdd0]; /* 0xdd0 */
+
+ /* 0xe00 is used as indicator for dump tools */
+ /* whether the kernel died with panic() or not */
+ __u32 panic_magic; /* 0xe00 */
+
+ __u8 pad13[0x1200-0xe04]; /* 0xe04 */
+
+ /* System info area */
+
+ __u64 floating_pt_save_area[16]; /* 0x1200 */
+ __u64 gpregs_save_area[16]; /* 0x1280 */
+ __u32 st_status_fixed_logout[4]; /* 0x1300 */
+ __u8 pad14[0x1318-0x1310]; /* 0x1310 */
+ __u32 prefixreg_save_area; /* 0x1318 */
+ __u32 fpt_creg_save_area; /* 0x131c */
+ __u8 pad15[0x1324-0x1320]; /* 0x1320 */
+ __u32 tod_progreg_save_area; /* 0x1324 */
+ __u32 cpu_timer_save_area[2]; /* 0x1328 */
+ __u32 clock_comp_save_area[2]; /* 0x1330 */
+ __u8 pad16[0x1340-0x1338]; /* 0x1338 */
+ __u32 access_regs_save_area[16]; /* 0x1340 */
+ __u64 cregs_save_area[16]; /* 0x1380 */
+
+ /* align to the top of the prefix area */
+
+ __u8 pad17[0x2000-0x1400]; /* 0x1400 */
+#endif /* !__s390x__ */
 } __attribute__((packed)); /* End structure*/
 
 #define S390_lowcore (*((struct _lowcore *) 0))
diff -urN linux-2.5.67/include/asm-s390/mmu_context.h linux-2.5.67-s390/include/asm-s390/mmu_context.h
--- linux-2.5.67/include/asm-s390/mmu_context.h Mon Apr 7 19:31:14 2003
+++ linux-2.5.67-s390/include/asm-s390/mmu_context.h Mon Apr 14 19:11:58 2003
@@ -27,12 +27,20 @@
         unsigned long pgd;
 
         if (prev != next) {
+#ifndef __s390x__
                 pgd = (__pa(next->pgd)&PAGE_MASK) |
                       (_SEGMENT_TABLE|USER_STD_MASK);
                 /* Load page tables */
                 asm volatile(" lctl 7,7,%0\n" /* secondary space */
                              " lctl 13,13,%0\n" /* home space */
                              : : "m" (pgd) );
+#else /* __s390x__ */
+ pgd = (__pa(next->pgd)&PAGE_MASK) | (_REGION_TABLE|USER_STD_MASK);
+ /* Load page tables */
+ asm volatile(" lctlg 7,7,%0\n" /* secondary space */
+ " lctlg 13,13,%0\n" /* home space */
+ : : "m" (pgd) );
+#endif /* __s390x__ */
         }
         set_bit(cpu, &next->cpu_vm_mask);
 }
diff -urN linux-2.5.67/include/asm-s390/module.h linux-2.5.67-s390/include/asm-s390/module.h
--- linux-2.5.67/include/asm-s390/module.h Mon Apr 7 19:30:33 2003
+++ linux-2.5.67-s390/include/asm-s390/module.h Mon Apr 14 19:11:58 2003
@@ -28,7 +28,7 @@
         struct mod_arch_syminfo *syminfo;
 };
 
-#ifdef CONFIG_ARCH_S390X
+#ifdef __s390x__
 #define ElfW(x) Elf64_ ## x
 #define ELFW(x) ELF64_ ## x
 #else
@@ -36,8 +36,11 @@
 #define ELFW(x) ELF32_ ## x
 #endif
 
+#define Elf_Addr ElfW(Addr)
+#define Elf_Rela ElfW(Rela)
 #define Elf_Shdr ElfW(Shdr)
 #define Elf_Sym ElfW(Sym)
 #define Elf_Ehdr ElfW(Ehdr)
+#define ELF_R_SYM ELFW(R_SYM)
 #define ELF_R_TYPE ELFW(R_TYPE)
 #endif /* _ASM_S390_MODULE_H */
diff -urN linux-2.5.67/include/asm-s390/msgbuf.h linux-2.5.67-s390/include/asm-s390/msgbuf.h
--- linux-2.5.67/include/asm-s390/msgbuf.h Mon Apr 7 19:31:43 2003
+++ linux-2.5.67-s390/include/asm-s390/msgbuf.h Mon Apr 14 19:11:58 2003
@@ -14,11 +14,17 @@
 struct msqid64_ds {
         struct ipc64_perm msg_perm;
         __kernel_time_t msg_stime; /* last msgsnd time */
+#ifndef __s390x__
         unsigned long __unused1;
+#endif /* ! __s390x__ */
         __kernel_time_t msg_rtime; /* last msgrcv time */
+#ifndef __s390x__
         unsigned long __unused2;
+#endif /* ! __s390x__ */
         __kernel_time_t msg_ctime; /* last change time */
+#ifndef __s390x__
         unsigned long __unused3;
+#endif /* ! __s390x__ */
         unsigned long msg_cbytes; /* current number of bytes on queue */
         unsigned long msg_qnum; /* number of messages in queue */
         unsigned long msg_qbytes; /* max number of bytes on queue */
diff -urN linux-2.5.67/include/asm-s390/page.h linux-2.5.67-s390/include/asm-s390/page.h
--- linux-2.5.67/include/asm-s390/page.h Mon Apr 7 19:30:44 2003
+++ linux-2.5.67-s390/include/asm-s390/page.h Mon Apr 14 19:11:58 2003
@@ -20,6 +20,8 @@
 #ifdef __KERNEL__
 #ifndef __ASSEMBLY__
 
+#ifndef __s390x__
+
 static inline void clear_page(void *page)
 {
         register_pair rp;
@@ -59,6 +61,48 @@
                               : "memory" );
 }
 
+#else /* __s390x__ */
+
+static inline void clear_page(void *page)
+{
+ asm volatile (" lgr 2,%0\n"
+ " lghi 3,4096\n"
+ " slgr 1,1\n"
+ " mvcl 2,0"
+ : : "a" ((void *) (page))
+ : "memory", "cc", "1", "2", "3" );
+}
+
+static inline void copy_page(void *to, void *from)
+{
+ if (MACHINE_HAS_MVPG)
+ asm volatile (" sgr 0,0\n"
+ " mvpg %0,%1"
+ : : "a" ((void *)(to)), "a" ((void *)(from))
+ : "memory", "cc", "0" );
+ else
+ asm volatile (" mvc 0(256,%0),0(%1)\n"
+ " mvc 256(256,%0),256(%1)\n"
+ " mvc 512(256,%0),512(%1)\n"
+ " mvc 768(256,%0),768(%1)\n"
+ " mvc 1024(256,%0),1024(%1)\n"
+ " mvc 1280(256,%0),1280(%1)\n"
+ " mvc 1536(256,%0),1536(%1)\n"
+ " mvc 1792(256,%0),1792(%1)\n"
+ " mvc 2048(256,%0),2048(%1)\n"
+ " mvc 2304(256,%0),2304(%1)\n"
+ " mvc 2560(256,%0),2560(%1)\n"
+ " mvc 2816(256,%0),2816(%1)\n"
+ " mvc 3072(256,%0),3072(%1)\n"
+ " mvc 3328(256,%0),3328(%1)\n"
+ " mvc 3584(256,%0),3584(%1)\n"
+ " mvc 3840(256,%0),3840(%1)\n"
+ : : "a"((void *)(to)),"a"((void *)(from))
+ : "memory" );
+}
+
+#endif /* __s390x__ */
+
 #define clear_user_page(page, vaddr, pg) clear_page(page)
 #define copy_user_page(to, from, vaddr, pg) copy_page(to, from)
 
@@ -79,7 +123,15 @@
 /*
  * These are used to make use of C type-checking..
  */
+
+typedef struct { unsigned long pgprot; } pgprot_t;
 typedef struct { unsigned long pte; } pte_t;
+
+#define pte_val(x) ((x).pte)
+#define pgprot_val(x) ((x).pgprot)
+
+#ifndef __s390x__
+
 typedef struct { unsigned long pmd; } pmd_t;
 typedef struct {
         unsigned long pgd0;
@@ -87,12 +139,23 @@
         unsigned long pgd2;
         unsigned long pgd3;
         } pgd_t;
-typedef struct { unsigned long pgprot; } pgprot_t;
 
-#define pte_val(x) ((x).pte)
 #define pmd_val(x) ((x).pmd)
 #define pgd_val(x) ((x).pgd0)
-#define pgprot_val(x) ((x).pgprot)
+
+#else /* __s390x__ */
+
+typedef struct {
+ unsigned long pmd0;
+ unsigned long pmd1;
+ } pmd_t;
+typedef struct { unsigned long pgd; } pgd_t;
+
+#define pmd_val(x) ((x).pmd0)
+#define pmd_val1(x) ((x).pmd1)
+#define pgd_val(x) ((x).pgd)
+
+#endif /* __s390x__ */
 
 #define __pte(x) ((pte_t) { (x) } )
 #define __pmd(x) ((pmd_t) { (x) } )
diff -urN linux-2.5.67/include/asm-s390/pgalloc.h linux-2.5.67-s390/include/asm-s390/pgalloc.h
--- linux-2.5.67/include/asm-s390/pgalloc.h Mon Apr 7 19:31:51 2003
+++ linux-2.5.67-s390/include/asm-s390/pgalloc.h Mon Apr 14 19:11:58 2003
@@ -1,5 +1,5 @@
 /*
- * include/asm-s390/bugs.h
+ * include/asm-s390/pgalloc.h
  *
  * S390 version
  * Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
@@ -32,35 +32,79 @@
         pgd_t *pgd;
         int i;
 
+#ifndef __s390x__
         pgd = (pgd_t *) __get_free_pages(GFP_KERNEL,1);
         if (pgd != NULL)
                 for (i = 0; i < USER_PTRS_PER_PGD; i++)
                         pmd_clear(pmd_offset(pgd + i, i*PGDIR_SIZE));
+#else /* __s390x__ */
+ pgd = (pgd_t *) __get_free_pages(GFP_KERNEL,2);
+ if (pgd != NULL)
+ for (i = 0; i < PTRS_PER_PGD; i++)
+ pgd_clear(pgd + i);
+#endif /* __s390x__ */
         return pgd;
 }
 
 static inline void pgd_free(pgd_t *pgd)
 {
+#ifndef __s390x__
         free_pages((unsigned long) pgd, 1);
+#else /* __s390x__ */
+ free_pages((unsigned long) pgd, 2);
+#endif /* __s390x__ */
 }
 
+#ifndef __s390x__
 /*
  * page middle directory allocation/free routines.
- * We don't use pmd cache, so these are dummy routines. This
+ * We use pmd cache only on s390x, so these are dummy routines. This
  * code never triggers because the pgd will always be present.
  */
 #define pmd_alloc_one(mm,address) ({ BUG(); ((pmd_t *)2); })
 #define pmd_free(x) do { } while (0)
 #define __pmd_free_tlb(tlb,x) do { } while (0)
 #define pgd_populate(mm, pmd, pte) BUG()
+#else /* __s390x__ */
+static inline pmd_t * pmd_alloc_one(struct mm_struct *mm, unsigned long vmaddr)
+{
+ pmd_t *pmd;
+ int i;
+
+ pmd = (pmd_t *) __get_free_pages(GFP_KERNEL, 2);
+ if (pmd != NULL) {
+ for (i=0; i < PTRS_PER_PMD; i++)
+ pmd_clear(pmd+i);
+ }
+ return pmd;
+}
+
+static inline void pmd_free (pmd_t *pmd)
+{
+ free_pages((unsigned long) pmd, 2);
+}
+
+#define __pmd_free_tlb(tlb,pmd) pmd_free(pmd)
+
+static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmd)
+{
+ pgd_val(*pgd) = _PGD_ENTRY | __pa(pmd);
+}
+
+#endif /* __s390x__ */
 
 static inline void
 pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, pte_t *pte)
 {
+#ifndef __s390x__
         pmd_val(pmd[0]) = _PAGE_TABLE + __pa(pte);
         pmd_val(pmd[1]) = _PAGE_TABLE + __pa(pte+256);
         pmd_val(pmd[2]) = _PAGE_TABLE + __pa(pte+512);
         pmd_val(pmd[3]) = _PAGE_TABLE + __pa(pte+768);
+#else /* __s390x__ */
+ pmd_val(*pmd) = _PMD_ENTRY + __pa(pte);
+ pmd_val1(*pmd) = _PMD_ENTRY + __pa(pte+256);
+#endif /* __s390x__ */
 }
 
 static inline void
@@ -122,11 +166,16 @@
                                     unsigned long address, pte_t *ptep)
 {
         pte_t pte = *ptep;
+#ifndef __s390x__
         if (!(pte_val(pte) & _PAGE_INVALID)) {
                 /* S390 has 1mb segments, we are emulating 4MB segments */
                 pte_t *pto = (pte_t *) (((unsigned long) ptep) & 0x7ffffc00);
                 __asm__ __volatile__ ("ipte %0,%1" : : "a" (pto), "a" (address));
         }
+#else /* __s390x__ */
+ if (!(pte_val(pte) & _PAGE_INVALID))
+ __asm__ __volatile__ ("ipte %0,%1" : : "a" (ptep), "a" (address));
+#endif /* __s390x__ */
         pte_clear(ptep);
         return pte;
 }
diff -urN linux-2.5.67/include/asm-s390/pgtable.h linux-2.5.67-s390/include/asm-s390/pgtable.h
--- linux-2.5.67/include/asm-s390/pgtable.h Mon Apr 14 19:11:45 2003
+++ linux-2.5.67-s390/include/asm-s390/pgtable.h Mon Apr 14 19:11:58 2003
@@ -14,10 +14,12 @@
 #define _ASM_S390_PGTABLE_H
 
 /*
- * The Linux memory management assumes a three-level page table setup. On
- * the S390, we use that, but "fold" the mid level into the top-level page
- * table, so that we physically have the same two-level page table as the
- * S390 mmu expects.
+ * The Linux memory management assumes a three-level page table setup. For
+ * s390 31 bit we "fold" the mid level into the top-level page table, so
+ * that we physically have the same two-level page table as the s390 mmu
+ * expects in 31 bit mode. For s390 64 bit we use three of the five levels
+ * the hardware provides (region first and region second tables are not
+ * used).
  *
  * The "pgd_xxx()" functions are trivial for a folded two-level
  * setup: the pgd is never bad, and a pmd always exists (as it's folded
@@ -50,13 +52,18 @@
 /*
  * PMD_SHIFT determines the size of the area a second-level page
  * table can map
+ * PGDIR_SHIFT determines what a third-level page table entry can map
  */
-#define PMD_SHIFT 22
+#ifndef __s390x__
+# define PMD_SHIFT 22
+# define PGDIR_SHIFT 22
+#else /* __s390x__ */
+# define PMD_SHIFT 21
+# define PGDIR_SHIFT 31
+#endif /* __s390x__ */
+
 #define PMD_SIZE (1UL << PMD_SHIFT)
 #define PMD_MASK (~(PMD_SIZE-1))
-
-/* PGDIR_SHIFT determines what a third-level page table entry can map */
-#define PGDIR_SHIFT 22
 #define PGDIR_SIZE (1UL << PGDIR_SHIFT)
 #define PGDIR_MASK (~(PGDIR_SIZE-1))
 
@@ -66,24 +73,37 @@
  * for S390 segment-table entries are combined to one PGD
  * that leads to 1024 pte per pgd
  */
-#define PTRS_PER_PTE 1024
-#define PTRS_PER_PMD 1
-#define PTRS_PER_PGD 512
+#ifndef __s390x__
+# define PTRS_PER_PTE 1024
+# define PTRS_PER_PMD 1
+# define PTRS_PER_PGD 512
+#else /* __s390x__ */
+# define PTRS_PER_PTE 512
+# define PTRS_PER_PMD 1024
+# define PTRS_PER_PGD 2048
+#endif /* __s390x__ */
 
 /*
  * pgd entries used up by user/kernel:
  */
-#define USER_PTRS_PER_PGD 512
-#define USER_PGD_PTRS 512
-#define KERNEL_PGD_PTRS 512
-#define FIRST_USER_PGD_NR 0
+#ifndef __s390x__
+# define USER_PTRS_PER_PGD 512
+# define USER_PGD_PTRS 512
+# define KERNEL_PGD_PTRS 512
+# define FIRST_USER_PGD_NR 0
+#else /* __s390x__ */
+# define USER_PTRS_PER_PGD 2048
+# define USER_PGD_PTRS 2048
+# define KERNEL_PGD_PTRS 2048
+# define FIRST_USER_PGD_NR 0
+#endif /* __s390x__ */
 
 #define pte_ERROR(e) \
- printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
+ printk("%s:%d: bad pte %p.\n", __FILE__, __LINE__, (void *) pte_val(e))
 #define pmd_ERROR(e) \
- printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e))
+ printk("%s:%d: bad pmd %p.\n", __FILE__, __LINE__, (void *) pmd_val(e))
 #define pgd_ERROR(e) \
- printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
+ printk("%s:%d: bad pgd %p.\n", __FILE__, __LINE__, (void *) pgd_val(e))
 
 #ifndef __ASSEMBLY__
 /*
@@ -98,11 +118,15 @@
 #define VMALLOC_START (((unsigned long) high_memory + VMALLOC_OFFSET) \
                          & ~(VMALLOC_OFFSET-1))
 #define VMALLOC_VMADDR(x) ((unsigned long)(x))
-#define VMALLOC_END (0x7fffffffL)
+#ifndef __s390x__
+# define VMALLOC_END (0x7fffffffL)
+#else /* __s390x__ */
+# define VMALLOC_END (0x40000000000L)
+#endif /* __s390x__ */
 
 
 /*
- * A pagetable entry of S390 has following format:
+ * A 31 bit pagetable entry of S390 has following format:
  * | PFRA | | OS |
  * 0 0IP0
  * 00000000001111111111222222222233
@@ -111,7 +135,7 @@
  * I Page-Invalid Bit: Page is not available for address-translation
  * P Page-Protection Bit: Store access not possible for page
  *
- * A segmenttable entry of S390 has following format:
+ * A 31 bit segmenttable entry of S390 has following format:
  * | P-table origin | |PTL
  * 0 IC
  * 00000000001111111111222222222233
@@ -121,7 +145,7 @@
  * C Common-Segment Bit: Segment is not private (PoP 3-30)
  * PTL Page-Table-Length: Page-table length (PTL+1*16 entries -> up to 256)
  *
- * The segmenttable origin of S390 has following format:
+ * The 31 bit segmenttable origin of S390 has following format:
  *
  * |S-table origin | | STL |
  * X **GPS
@@ -134,6 +158,46 @@
  * S Storage-Alteration:
  * STL Segment-Table-Length: Segment-table length (STL+1*16 entries -> up to 2048)
  *
+ * A 64 bit pagetable entry of S390 has following format:
+ * | PFRA |0IP0| OS |
+ * 0000000000111111111122222222223333333333444444444455555555556666
+ * 0123456789012345678901234567890123456789012345678901234567890123
+ *
+ * I Page-Invalid Bit: Page is not available for address-translation
+ * P Page-Protection Bit: Store access not possible for page
+ *
+ * A 64 bit segmenttable entry of S390 has following format:
+ * | P-table origin | TT
+ * 0000000000111111111122222222223333333333444444444455555555556666
+ * 0123456789012345678901234567890123456789012345678901234567890123
+ *
+ * I Segment-Invalid Bit: Segment is not available for address-translation
+ * C Common-Segment Bit: Segment is not private (PoP 3-30)
+ * P Page-Protection Bit: Store access not possible for page
+ * TT Type 00
+ *
+ * A 64 bit region table entry of S390 has following format:
+ * | S-table origin | TF TTTL
+ * 0000000000111111111122222222223333333333444444444455555555556666
+ * 0123456789012345678901234567890123456789012345678901234567890123
+ *
+ * I Segment-Invalid Bit: Segment is not available for address-translation
+ * TT Type 01
+ * TF
+ * TL Table lenght
+ *
+ * The 64 bit regiontable origin of S390 has following format:
+ * | region table origon | DTTL
+ * 0000000000111111111122222222223333333333444444444455555555556666
+ * 0123456789012345678901234567890123456789012345678901234567890123
+ *
+ * X Space-Switch event:
+ * G Segment-Invalid Bit:
+ * P Private-Space Bit:
+ * S Storage-Alteration:
+ * R Real space
+ * TL Table-Length:
+ *
  * A storage key has the following format:
  * | ACC |F|R|C|0|
  * 0 3 4 5 6 7
@@ -158,6 +222,8 @@
 #define _PAGE_INVALID_SWAP 0x200
 #define _PAGE_INVALID_FILE 0x201
 
+#ifndef __s390x__
+
 /* Bits in the segment table entry */
 #define _PAGE_TABLE_LEN 0xf /* only full page-tables */
 #define _PAGE_TABLE_COM 0x10 /* common page-table */
@@ -186,6 +252,32 @@
 
 #define USER_STD_MASK 0x00000080UL
 
+#else /* __s390x__ */
+
+/* Bits in the segment table entry */
+#define _PMD_ENTRY_INV 0x20 /* invalid segment table entry */
+#define _PMD_ENTRY 0x00
+
+/* Bits in the region third table entry */
+#define _PGD_ENTRY_INV 0x20 /* invalid region table entry */
+#define _PGD_ENTRY 0x07
+
+/*
+ * User and kernel page directory
+ */
+#define _REGION_THIRD 0x4
+#define _REGION_THIRD_LEN 0x3
+#define _REGION_TABLE (_REGION_THIRD|_REGION_THIRD_LEN|0x40|0x100)
+#define _KERN_REGION_TABLE (_REGION_THIRD|_REGION_THIRD_LEN)
+
+#define USER_STD_MASK 0x0000000000000080UL
+
+/* Bits in the storage key */
+#define _PAGE_CHANGED 0x02 /* HW changed bit */
+#define _PAGE_REFERENCED 0x04 /* HW referenced bit */
+
+#endif /* __s390x__ */
+
 /*
  * No mapping available
  */
@@ -195,7 +287,7 @@
 #define PAGE_RO_PRIVATE __pgprot(_PAGE_RO|_PAGE_ISCLEAN)
 #define PAGE_COPY __pgprot(_PAGE_RO|_PAGE_ISCLEAN)
 #define PAGE_SHARED __pgprot(0)
-#define PAGE_KERNEL __pgprot(0)
+#define PAGE_KERNEL __pgprot(_PAGE_ISCLEAN)
 
 /*
  * The S390 can't do page protection for execute, and considers that the
@@ -243,6 +335,8 @@
 /*
  * pgd/pmd/pte query functions
  */
+#ifndef __s390x__
+
 extern inline int pgd_present(pgd_t pgd) { return 1; }
 extern inline int pgd_none(pgd_t pgd) { return 0; }
 extern inline int pgd_bad(pgd_t pgd) { return 0; }
@@ -254,6 +348,40 @@
         return (pmd_val(pmd) & (~PAGE_MASK & ~_PAGE_TABLE_INV)) != _PAGE_TABLE;
 }
 
+#else /* __s390x__ */
+
+extern inline int pgd_present(pgd_t pgd)
+{
+ return (pgd_val(pgd) & ~PAGE_MASK) == _PGD_ENTRY;
+}
+
+extern inline int pgd_none(pgd_t pgd)
+{
+ return pgd_val(pgd) & _PGD_ENTRY_INV;
+}
+
+extern inline int pgd_bad(pgd_t pgd)
+{
+ return (pgd_val(pgd) & (~PAGE_MASK & ~_PGD_ENTRY_INV)) != _PGD_ENTRY;
+}
+
+extern inline int pmd_present(pmd_t pmd)
+{
+ return (pmd_val(pmd) & ~PAGE_MASK) == _PMD_ENTRY;
+}
+
+extern inline int pmd_none(pmd_t pmd)
+{
+ return pmd_val(pmd) & _PMD_ENTRY_INV;
+}
+
+extern inline int pmd_bad(pmd_t pmd)
+{
+ return (pmd_val(pmd) & (~PAGE_MASK & ~_PMD_ENTRY_INV)) != _PMD_ENTRY;
+}
+
+#endif /* __s390x__ */
+
 extern inline int pte_none(pte_t pte)
 {
         return (pte_val(pte) & _PAGE_INVALID_MASK) == _PAGE_INVALID_EMPTY;
@@ -302,6 +430,9 @@
 /*
  * pgd/pmd/pte modification functions
  */
+
+#ifndef __s390x__
+
 extern inline void pgd_clear(pgd_t * pgdp) { }
 
 extern inline void pmd_clear(pmd_t * pmdp)
@@ -312,6 +443,21 @@
         pmd_val(pmdp[3]) = _PAGE_TABLE_INV;
 }
 
+#else /* __s390x__ */
+
+extern inline void pgd_clear(pgd_t * pgdp)
+{
+ pgd_val(*pgdp) = _PGD_ENTRY_INV | _PGD_ENTRY;
+}
+
+extern inline void pmd_clear(pmd_t * pmdp)
+{
+ pmd_val(*pmdp) = _PMD_ENTRY_INV | _PMD_ENTRY;
+ pmd_val1(*pmdp) = _PMD_ENTRY_INV | _PMD_ENTRY;
+}
+
+#endif /* __s390x__ */
+
 extern inline void pte_clear(pte_t *ptep)
 {
         pte_val(*ptep) = _PAGE_INVALID_EMPTY;
@@ -460,6 +606,18 @@
         __pte; \
 })
 
+#ifdef __s390x__
+
+#define pfn_pmd(pfn, pgprot) \
+({ \
+ pgprot_t __pgprot = (pgprot); \
+ unsigned long __physpage = __pa((pfn) << PAGE_SHIFT); \
+ pmd_t __pmd = __pmd(__physpage + pgprot_val(__pgprot)); \
+ __pmd; \
+})
+
+#endif /* __s390x__ */
+
 #define pte_pfn(x) (pte_val(x) >> PAGE_SHIFT)
 #define pte_page(x) pfn_to_page(pte_pfn(x))
 
@@ -476,12 +634,23 @@
 /* to find an entry in a kernel page-table-directory */
 #define pgd_offset_k(address) pgd_offset(&init_mm, address)
 
+#ifndef __s390x__
+
 /* Find an entry in the second-level page table.. */
 extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
 {
         return (pmd_t *) dir;
 }
 
+#else /* __s390x__ */
+
+/* Find an entry in the second-level page table.. */
+#define pmd_index(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
+#define pmd_offset(dir,addr) \
+ ((pmd_t *) pgd_page_kernel(*(dir)) + pmd_index(addr))
+
+#endif /* __s390x__ */
+
 /* Find an entry in the third-level page table.. */
 #define pte_index(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE-1))
 #define pte_offset_kernel(pmd, address) \
@@ -492,6 +661,7 @@
 #define pte_unmap_nested(pte) do { } while (0)
 
 /*
+ * 31 bit swap entry format:
  * A page-table entry has some bits we have to treat in a special way.
  * Bits 0, 20 and bit 23 have to be zero, otherwise an specification
  * exception will occur instead of a page translation exception. The
@@ -507,17 +677,38 @@
  * 0| offset |0110|type |0
  * 00000000001111111111222222222233
  * 01234567890123456789012345678901
+ *
+ * 64 bit swap entry format:
+ * A page-table entry has some bits we have to treat in a special way.
+ * Bits 52 and bit 55 have to be zero, otherwise an specification
+ * exception will occur instead of a page translation exception. The
+ * specifiation exception has the bad habit not to store necessary
+ * information in the lowcore.
+ * Bit 53 and bit 54 are the page invalid bit and the page protection
+ * bit. We set both to indicate a swapped page.
+ * Bit 63 is used as the software page present bit. If a page is
+ * swapped this obviously has to be zero.
+ * This leaves the bits 0-51 and bits 56-62 to store type and offset.
+ * We use the 7 bits from 56-62 for the type and the 52 bits from 0-51
+ * for the offset.
+ * | offset |0110|type |0
+ * 0000000000111111111122222222223333333333444444444455555555556666
+ * 0123456789012345678901234567890123456789012345678901234567890123
  */
 extern inline pte_t mk_swap_pte(unsigned long type, unsigned long offset)
 {
         pte_t pte;
         pte_val(pte) = (type << 1) | (offset << 12) | _PAGE_INVALID_SWAP;
+#ifndef __s390x__
         pte_val(pte) &= 0x7ffff6fe; /* better to be paranoid */
+#else /* __s390x__ */
+ pte_val(pte) &= 0xfffffffffffff6fe; /* better to be paranoid */
+#endif /* __s390x__ */
         return pte;
 }
 
 #define __swp_type(entry) (((entry).val >> 1) & 0x3f)
-#define __swp_offset(entry) (((entry).val >> 12) & 0x7FFFF )
+#define __swp_offset(entry) ((entry).val >> 12)
 #define __swp_entry(type,offset) ((swp_entry_t) { pte_val(mk_swap_pte((type),(offset))) })
 
 #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
@@ -525,7 +716,11 @@
 
 typedef pte_t *pte_addr_t;
 
-#define PTE_FILE_MAX_BITS 26
+#ifndef __s390x__
+# define PTE_FILE_MAX_BITS 26
+#else /* __s390x__ */
+# define PTE_FILE_MAX_BITS 59
+#endif /* __s390x__ */
 
 #define pte_to_pgoff(__pte) \
         ((((__pte).pte >> 12) << 7) + (((__pte).pte >> 1) & 0x7f))
@@ -543,5 +738,9 @@
  */
 #define pgtable_cache_init() do { } while (0)
 
+#ifdef __s390x__
+# define HAVE_ARCH_UNMAPPED_AREA
+#endif /* __s390x__ */
+
 #endif /* _S390_PAGE_H */
 

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Tue Apr 15 2003 - 22:00:32 EST