diff options
Diffstat (limited to 'include/asm-s390')
-rw-r--r-- | include/asm-s390/airq.h | 19 | ||||
-rw-r--r-- | include/asm-s390/bitops.h | 556 | ||||
-rw-r--r-- | include/asm-s390/cacheflush.h | 4 | ||||
-rw-r--r-- | include/asm-s390/ccwgroup.h | 2 | ||||
-rw-r--r-- | include/asm-s390/cio.h | 4 | ||||
-rw-r--r-- | include/asm-s390/compat.h | 2 | ||||
-rw-r--r-- | include/asm-s390/cputime.h | 1 | ||||
-rw-r--r-- | include/asm-s390/dasd.h | 2 | ||||
-rw-r--r-- | include/asm-s390/ipl.h | 8 | ||||
-rw-r--r-- | include/asm-s390/mmu_context.h | 27 | ||||
-rw-r--r-- | include/asm-s390/percpu.h | 62 | ||||
-rw-r--r-- | include/asm-s390/pgalloc.h | 14 | ||||
-rw-r--r-- | include/asm-s390/pgtable.h | 60 | ||||
-rw-r--r-- | include/asm-s390/processor.h | 7 | ||||
-rw-r--r-- | include/asm-s390/ptrace.h | 8 | ||||
-rw-r--r-- | include/asm-s390/qdio.h | 2 | ||||
-rw-r--r-- | include/asm-s390/rwsem.h | 4 | ||||
-rw-r--r-- | include/asm-s390/sclp.h | 20 | ||||
-rw-r--r-- | include/asm-s390/smp.h | 5 | ||||
-rw-r--r-- | include/asm-s390/socket.h | 2 | ||||
-rw-r--r-- | include/asm-s390/spinlock.h | 32 | ||||
-rw-r--r-- | include/asm-s390/spinlock_types.h | 1 | ||||
-rw-r--r-- | include/asm-s390/system.h | 5 | ||||
-rw-r--r-- | include/asm-s390/tlb.h | 8 | ||||
-rw-r--r-- | include/asm-s390/tlbflush.h | 32 | ||||
-rw-r--r-- | include/asm-s390/zcrypt.h | 2 |
26 files changed, 438 insertions, 451 deletions
diff --git a/include/asm-s390/airq.h b/include/asm-s390/airq.h new file mode 100644 index 000000000000..41d028cb52a4 --- /dev/null +++ b/include/asm-s390/airq.h @@ -0,0 +1,19 @@ +/* + * include/asm-s390/airq.h + * + * Copyright IBM Corp. 2002,2007 + * Author(s): Ingo Adlung <adlung@de.ibm.com> + * Cornelia Huck <cornelia.huck@de.ibm.com> + * Arnd Bergmann <arndb@de.ibm.com> + * Peter Oberparleiter <peter.oberparleiter@de.ibm.com> + */ + +#ifndef _ASM_S390_AIRQ_H +#define _ASM_S390_AIRQ_H + +typedef void (*adapter_int_handler_t)(void *, void *); + +void *s390_register_adapter_interrupt(adapter_int_handler_t, void *); +void s390_unregister_adapter_interrupt(void *); + +#endif /* _ASM_S390_AIRQ_H */ diff --git a/include/asm-s390/bitops.h b/include/asm-s390/bitops.h index 34d9a6357c38..882db054110c 100644 --- a/include/asm-s390/bitops.h +++ b/include/asm-s390/bitops.h @@ -440,242 +440,256 @@ __constant_test_bit(unsigned long nr, const volatile unsigned long *addr) { __test_bit((nr),(addr)) ) /* - * ffz = Find First Zero in word. Undefined if no zero exists, - * so code should check against ~0UL first.. + * Optimized find bit helper functions. */ -static inline unsigned long ffz(unsigned long word) + +/** + * __ffz_word_loop - find byte offset of first long != -1UL + * @addr: pointer to array of unsigned long + * @size: size of the array in bits + */ +static inline unsigned long __ffz_word_loop(const unsigned long *addr, + unsigned long size) { - unsigned long bit = 0; + typedef struct { long _[__BITOPS_WORDS(size)]; } addrtype; + unsigned long bytes = 0; + asm volatile( +#ifndef __s390x__ + " ahi %1,31\n" + " srl %1,5\n" + "0: c %2,0(%0,%3)\n" + " jne 1f\n" + " la %0,4(%0)\n" + " brct %1,0b\n" + "1:\n" +#else + " aghi %1,63\n" + " srlg %1,%1,6\n" + "0: cg %2,0(%0,%3)\n" + " jne 1f\n" + " la %0,8(%0)\n" + " brct %1,0b\n" + "1:\n" +#endif + : "+a" (bytes), "+d" (size) + : "d" (-1UL), "a" (addr), "m" (*(addrtype *) addr) + : "cc" ); + return bytes; +} + +/** + * __ffs_word_loop - find byte offset of first long != 0UL + * @addr: pointer to array of unsigned long + * @size: size of the array in bits + */ +static inline unsigned long __ffs_word_loop(const unsigned long *addr, + unsigned long size) +{ + typedef struct { long _[__BITOPS_WORDS(size)]; } addrtype; + unsigned long bytes = 0; + + asm volatile( +#ifndef __s390x__ + " ahi %1,31\n" + " srl %1,5\n" + "0: c %2,0(%0,%3)\n" + " jne 1f\n" + " la %0,4(%0)\n" + " brct %1,0b\n" + "1:\n" +#else + " aghi %1,63\n" + " srlg %1,%1,6\n" + "0: cg %2,0(%0,%3)\n" + " jne 1f\n" + " la %0,8(%0)\n" + " brct %1,0b\n" + "1:\n" +#endif + : "+a" (bytes), "+a" (size) + : "d" (0UL), "a" (addr), "m" (*(addrtype *) addr) + : "cc" ); + return bytes; +} + +/** + * __ffz_word - add number of the first unset bit + * @nr: base value the bit number is added to + * @word: the word that is searched for unset bits + */ +static inline unsigned long __ffz_word(unsigned long nr, unsigned long word) +{ #ifdef __s390x__ if (likely((word & 0xffffffff) == 0xffffffff)) { word >>= 32; - bit += 32; + nr += 32; } #endif if (likely((word & 0xffff) == 0xffff)) { word >>= 16; - bit += 16; + nr += 16; } if (likely((word & 0xff) == 0xff)) { word >>= 8; - bit += 8; + nr += 8; } - return bit + _zb_findmap[word & 0xff]; + return nr + _zb_findmap[(unsigned char) word]; } -/* - * __ffs = find first bit in word. Undefined if no bit exists, - * so code should check against 0UL first.. +/** + * __ffs_word - add number of the first set bit + * @nr: base value the bit number is added to + * @word: the word that is searched for set bits */ -static inline unsigned long __ffs (unsigned long word) +static inline unsigned long __ffs_word(unsigned long nr, unsigned long word) { - unsigned long bit = 0; - #ifdef __s390x__ if (likely((word & 0xffffffff) == 0)) { word >>= 32; - bit += 32; + nr += 32; } #endif if (likely((word & 0xffff) == 0)) { word >>= 16; - bit += 16; + nr += 16; } if (likely((word & 0xff) == 0)) { word >>= 8; - bit += 8; + nr += 8; } - return bit + _sb_findmap[word & 0xff]; + return nr + _sb_findmap[(unsigned char) word]; } -/* - * Find-bit routines.. - */ -#ifndef __s390x__ +/** + * __load_ulong_be - load big endian unsigned long + * @p: pointer to array of unsigned long + * @offset: byte offset of source value in the array + */ +static inline unsigned long __load_ulong_be(const unsigned long *p, + unsigned long offset) +{ + p = (unsigned long *)((unsigned long) p + offset); + return *p; +} -static inline int -find_first_zero_bit(const unsigned long * addr, unsigned long size) +/** + * __load_ulong_le - load little endian unsigned long + * @p: pointer to array of unsigned long + * @offset: byte offset of source value in the array + */ +static inline unsigned long __load_ulong_le(const unsigned long *p, + unsigned long offset) { - typedef struct { long _[__BITOPS_WORDS(size)]; } addrtype; - unsigned long cmp, count; - unsigned int res; + unsigned long word; - if (!size) - return 0; + p = (unsigned long *)((unsigned long) p + offset); +#ifndef __s390x__ asm volatile( - " lhi %1,-1\n" - " lr %2,%3\n" - " slr %0,%0\n" - " ahi %2,31\n" - " srl %2,5\n" - "0: c %1,0(%0,%4)\n" - " jne 1f\n" - " la %0,4(%0)\n" - " brct %2,0b\n" - " lr %0,%3\n" - " j 4f\n" - "1: l %2,0(%0,%4)\n" - " sll %0,3\n" - " lhi %1,0xff\n" - " tml %2,0xffff\n" - " jno 2f\n" - " ahi %0,16\n" - " srl %2,16\n" - "2: tml %2,0x00ff\n" - " jno 3f\n" - " ahi %0,8\n" - " srl %2,8\n" - "3: nr %2,%1\n" - " ic %2,0(%2,%5)\n" - " alr %0,%2\n" - "4:" - : "=&a" (res), "=&d" (cmp), "=&a" (count) - : "a" (size), "a" (addr), "a" (&_zb_findmap), - "m" (*(addrtype *) addr) : "cc"); - return (res < size) ? res : size; + " ic %0,0(%1)\n" + " icm %0,2,1(%1)\n" + " icm %0,4,2(%1)\n" + " icm %0,8,3(%1)" + : "=&d" (word) : "a" (p), "m" (*p) : "cc"); +#else + asm volatile( + " lrvg %0,%1" + : "=d" (word) : "m" (*p) ); +#endif + return word; } -static inline int -find_first_bit(const unsigned long * addr, unsigned long size) +/* + * The various find bit functions. + */ + +/* + * ffz - find first zero in word. + * @word: The word to search + * + * Undefined if no zero exists, so code should check against ~0UL first. + */ +static inline unsigned long ffz(unsigned long word) { - typedef struct { long _[__BITOPS_WORDS(size)]; } addrtype; - unsigned long cmp, count; - unsigned int res; + return __ffz_word(0, word); +} - if (!size) - return 0; - asm volatile( - " slr %1,%1\n" - " lr %2,%3\n" - " slr %0,%0\n" - " ahi %2,31\n" - " srl %2,5\n" - "0: c %1,0(%0,%4)\n" - " jne 1f\n" - " la %0,4(%0)\n" - " brct %2,0b\n" - " lr %0,%3\n" - " j 4f\n" - "1: l %2,0(%0,%4)\n" - " sll %0,3\n" - " lhi %1,0xff\n" - " tml %2,0xffff\n" - " jnz 2f\n" - " ahi %0,16\n" - " srl %2,16\n" - "2: tml %2,0x00ff\n" - " jnz 3f\n" - " ahi %0,8\n" - " srl %2,8\n" - "3: nr %2,%1\n" - " ic %2,0(%2,%5)\n" - " alr %0,%2\n" - "4:" - : "=&a" (res), "=&d" (cmp), "=&a" (count) - : "a" (size), "a" (addr), "a" (&_sb_findmap), - "m" (*(addrtype *) addr) : "cc"); - return (res < size) ? res : size; +/** + * __ffs - find first bit in word. + * @word: The word to search + * + * Undefined if no bit exists, so code should check against 0 first. + */ +static inline unsigned long __ffs (unsigned long word) +{ + return __ffs_word(0, word); } -#else /* __s390x__ */ +/** + * ffs - find first bit set + * @x: the word to search + * + * This is defined the same way as + * the libc and compiler builtin ffs routines, therefore + * differs in spirit from the above ffz (man ffs). + */ +static inline int ffs(int x) +{ + if (!x) + return 0; + return __ffs_word(1, x); +} -static inline unsigned long -find_first_zero_bit(const unsigned long * addr, unsigned long size) +/** + * find_first_zero_bit - find the first zero bit in a memory region + * @addr: The address to start the search at + * @size: The maximum size to search + * + * Returns the bit-number of the first zero bit, not the number of the byte + * containing a bit. + */ +static inline unsigned long find_first_zero_bit(const unsigned long *addr, + unsigned long size) { - typedef struct { long _[__BITOPS_WORDS(size)]; } addrtype; - unsigned long res, cmp, count; + unsigned long bytes, bits; if (!size) return 0; - asm volatile( - " 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" - " la %0,8(%0)\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), - "m" (*(addrtype *) addr) : "cc"); - return (res < size) ? res : size; -} - -static inline unsigned long -find_first_bit(const unsigned long * addr, unsigned long size) + bytes = __ffz_word_loop(addr, size); + bits = __ffz_word(bytes*8, __load_ulong_be(addr, bytes)); + return (bits < size) ? bits : size; +} + +/** + * find_first_bit - find the first set bit in a memory region + * @addr: The address to start the search at + * @size: The maximum size to search + * + * Returns the bit-number of the first set bit, not the number of the byte + * containing a bit. + */ +static inline unsigned long find_first_bit(const unsigned long * addr, + unsigned long size) { - typedef struct { long _[__BITOPS_WORDS(size)]; } addrtype; - unsigned long res, cmp, count; + unsigned long bytes, bits; if (!size) return 0; - asm volatile( - " 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), - "m" (*(addrtype *) addr) : "cc"); - return (res < size) ? res : size; + bytes = __ffs_word_loop(addr, size); + bits = __ffs_word(bytes*8, __load_ulong_be(addr, bytes)); + return (bits < size) ? bits : size; } -#endif /* __s390x__ */ - -static inline int -find_next_zero_bit (const unsigned long * addr, unsigned long size, - unsigned long offset) +/** + * find_next_zero_bit - find the first zero bit in a memory region + * @addr: The address to base the search on + * @offset: The bitnumber to start searching at + * @size: The maximum size to search + */ +static inline int find_next_zero_bit (const unsigned long * addr, + unsigned long size, + unsigned long offset) { const unsigned long *p; unsigned long bit, set; @@ -688,10 +702,10 @@ find_next_zero_bit (const unsigned long * addr, unsigned long size, p = addr + offset / __BITOPS_WORDSIZE; if (bit) { /* - * s390 version of ffz returns __BITOPS_WORDSIZE + * __ffz_word returns __BITOPS_WORDSIZE * if no zero bit is present in the word. */ - set = ffz(*p >> bit) + bit; + set = __ffz_word(0, *p >> bit) + bit; if (set >= size) return size + offset; if (set < __BITOPS_WORDSIZE) @@ -703,9 +717,15 @@ find_next_zero_bit (const unsigned long * addr, unsigned long size, return offset + find_first_zero_bit(p, size); } -static inline int -find_next_bit (const unsigned long * addr, unsigned long size, - unsigned long offset) +/** + * find_next_bit - find the first set bit in a memory region + * @addr: The address to base the search on + * @offset: The bitnumber to start searching at + * @size: The maximum size to search + */ +static inline int find_next_bit (const unsigned long * addr, + unsigned long size, + unsigned long offset) { const unsigned long *p; unsigned long bit, set; @@ -718,10 +738,10 @@ find_next_bit (const unsigned long * addr, unsigned long size, p = addr + offset / __BITOPS_WORDSIZE; if (bit) { /* - * s390 version of __ffs returns __BITOPS_WORDSIZE + * __ffs_word returns __BITOPS_WORDSIZE * if no one bit is present in the word. */ - set = __ffs(*p & (~0UL << bit)); + set = __ffs_word(0, *p & (~0UL << bit)); if (set >= size) return size + offset; if (set < __BITOPS_WORDSIZE) @@ -744,8 +764,6 @@ static inline int sched_find_first_bit(unsigned long *b) return find_first_bit(b, 140); } -#include <asm-generic/bitops/ffs.h> - #include <asm-generic/bitops/fls.h> #include <asm-generic/bitops/fls64.h> @@ -773,105 +791,22 @@ static inline int sched_find_first_bit(unsigned long *b) #define ext2_test_bit(nr, addr) \ test_bit((nr)^(__BITOPS_WORDSIZE - 8), (unsigned long *)addr) -#ifndef __s390x__ - -static inline int -ext2_find_first_zero_bit(void *vaddr, unsigned int size) +static inline int ext2_find_first_zero_bit(void *vaddr, unsigned int size) { - typedef struct { long _[__BITOPS_WORDS(size)]; } addrtype; - unsigned long cmp, count; - unsigned int res; + unsigned long bytes, bits; if (!size) return 0; - asm volatile( - " lhi %1,-1\n" - " lr %2,%3\n" - " ahi %2,31\n" - " srl %2,5\n" - " slr %0,%0\n" - "0: cl %1,0(%0,%4)\n" - " jne 1f\n" - " ahi %0,4\n" - " brct %2,0b\n" - " lr %0,%3\n" - " j 4f\n" - "1: l %2,0(%0,%4)\n" - " sll %0,3\n" - " ahi %0,24\n" - " lhi %1,0xff\n" - " tmh %2,0xffff\n" - " jo 2f\n" - " ahi %0,-16\n" - " srl %2,16\n" - "2: tml %2,0xff00\n" - " jo 3f\n" - " ahi %0,-8\n" - " srl %2,8\n" - "3: nr %2,%1\n" - " ic %2,0(%2,%5)\n" - " alr %0,%2\n" - "4:" - : "=&a" (res), "=&d" (cmp), "=&a" (count) - : "a" (size), "a" (vaddr), "a" (&_zb_findmap), - "m" (*(addrtype *) vaddr) : "cc"); - return (res < size) ? res : size; + bytes = __ffz_word_loop(vaddr, size); + bits = __ffz_word(bytes*8, __load_ulong_le(vaddr, bytes)); + return (bits < size) ? bits : size; } -#else /* __s390x__ */ - -static inline unsigned long -ext2_find_first_zero_bit(void *vaddr, unsigned long size) -{ - typedef struct { long _[__BITOPS_WORDS(size)]; } addrtype; - unsigned long res, cmp, count; - - if (!size) - return 0; - asm volatile( - " 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), - "m" (*(addrtype *) vaddr) : "cc"); - return (res < size) ? res : size; -} - -#endif /* __s390x__ */ - -static inline int -ext2_find_next_zero_bit(void *vaddr, unsigned long size, unsigned long offset) +static inline int ext2_find_next_zero_bit(void *vaddr, unsigned long size, + unsigned long offset) { unsigned long *addr = vaddr, *p; - unsigned long word, bit, set; + unsigned long bit, set; if (offset >= size) return size; @@ -880,23 +815,11 @@ ext2_find_next_zero_bit(void *vaddr, unsigned long size, unsigned long offset) size -= offset; p = addr + offset / __BITOPS_WORDSIZE; if (bit) { -#ifndef __s390x__ - asm volatile( - " ic %0,0(%1)\n" - " icm %0,2,1(%1)\n" - " icm %0,4,2(%1)\n" - " icm %0,8,3(%1)" - : "=&a" (word) : "a" (p), "m" (*p) : "cc"); -#else - asm volatile( - " lrvg %0,%1" - : "=a" (word) : "m" (*p) ); -#endif /* * s390 version of ffz returns __BITOPS_WORDSIZE * if no zero bit is present in the word. */ - set = ffz(word >> bit) + bit; + set = ffz(__load_ulong_le(p, 0) >> bit) + bit; if (set >= size) return size + offset; if (set < __BITOPS_WORDSIZE) @@ -908,6 +831,47 @@ ext2_find_next_zero_bit(void *vaddr, unsigned long size, unsigned long offset) return offset + ext2_find_first_zero_bit(p, size); } +static inline unsigned long ext2_find_first_bit(void *vaddr, + unsigned long size) +{ + unsigned long bytes, bits; + + if (!size) + return 0; + bytes = __ffs_word_loop(vaddr, size); + bits = __ffs_word(bytes*8, __load_ulong_le(vaddr, bytes)); + return (bits < size) ? bits : size; +} + +static inline int ext2_find_next_bit(void *vaddr, unsigned long size, + unsigned long offset) +{ + unsigned long *addr = vaddr, *p; + unsigned long bit, set; + + if (offset >= size) + return size; + bit = offset & (__BITOPS_WORDSIZE - 1); + offset -= bit; + size -= offset; + p = addr + offset / __BITOPS_WORDSIZE; + if (bit) { + /* + * s390 version of ffz returns __BITOPS_WORDSIZE + * if no zero bit is present in the word. + */ + set = ffs(__load_ulong_le(p, 0) >> bit) + bit; + if (set >= size) + return size + offset; + if (set < __BITOPS_WORDSIZE) + return set + offset; + offset += __BITOPS_WORDSIZE; + size -= __BITOPS_WORDSIZE; + p++; + } + return offset + ext2_find_first_bit(p, size); +} + #include <asm-generic/bitops/minix.h> #endif /* __KERNEL__ */ diff --git a/include/asm-s390/cacheflush.h b/include/asm-s390/cacheflush.h index f7cade8083f3..49d5af916d01 100644 --- a/include/asm-s390/cacheflush.h +++ b/include/asm-s390/cacheflush.h @@ -24,4 +24,8 @@ #define copy_from_user_page(vma, page, vaddr, dst, src, len) \ memcpy(dst, src, len) +#ifdef CONFIG_DEBUG_PAGEALLOC +void kernel_map_pages(struct page *page, int numpages, int enable); +#endif + #endif /* _S390_CACHEFLUSH_H */ diff --git a/include/asm-s390/ccwgroup.h b/include/asm-s390/ccwgroup.h index 7109c7cab87e..289053ef5e60 100644 --- a/include/asm-s390/ccwgroup.h +++ b/include/asm-s390/ccwgroup.h @@ -37,6 +37,7 @@ struct ccwgroup_device { * @remove: function called on remove * @set_online: function called when device is set online * @set_offline: function called when device is set offline + * @shutdown: function called when device is shut down * @driver: embedded driver structure */ struct ccwgroup_driver { @@ -49,6 +50,7 @@ struct ccwgroup_driver { void (*remove) (struct ccwgroup_device *); int (*set_online) (struct ccwgroup_device *); int (*set_offline) (struct ccwgroup_device *); + void (*shutdown)(struct ccwgroup_device *); struct device_driver driver; }; diff --git a/include/asm-s390/cio.h b/include/asm-s390/cio.h index 2f08c16e44ad..123b557c3ff4 100644 --- a/include/asm-s390/cio.h +++ b/include/asm-s390/cio.h @@ -24,8 +24,8 @@ * @fmt: format * @pfch: prefetch * @isic: initial-status interruption control - * @alcc: adress-limit checking control - * @ssi: supress-suspended interruption + * @alcc: address-limit checking control + * @ssi: suppress-suspended interruption * @zcc: zero condition code * @ectl: extended control * @pno: path not operational diff --git a/include/asm-s390/compat.h b/include/asm-s390/compat.h index 7f4ad623f7d5..de065b32381a 100644 --- a/include/asm-s390/compat.h +++ b/include/asm-s390/compat.h @@ -149,7 +149,7 @@ typedef u32 compat_sigset_word; * 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. + * appropriately converted them already. */ typedef u32 compat_uptr_t; diff --git a/include/asm-s390/cputime.h b/include/asm-s390/cputime.h index 4b3ef7cad115..133ce054fc89 100644 --- a/include/asm-s390/cputime.h +++ b/include/asm-s390/cputime.h @@ -54,6 +54,7 @@ __div(unsigned long long n, unsigned int base) #define cputime_lt(__a, __b) ((__a) < (__b)) #define cputime_le(__a, __b) ((__a) <= (__b)) #define cputime_to_jiffies(__ct) (__div((__ct), 1000000 / HZ)) +#define cputime_to_scaled(__ct) (__ct) #define jiffies_to_cputime(__hz) ((cputime_t)(__hz) * (1000000 / HZ)) #define cputime64_zero (0ULL) diff --git a/include/asm-s390/dasd.h b/include/asm-s390/dasd.h index 604f68fa6f56..3f002e13d024 100644 --- a/include/asm-s390/dasd.h +++ b/include/asm-s390/dasd.h @@ -105,7 +105,7 @@ typedef struct dasd_information_t { } dasd_information_t; /* - * Read Subsystem Data - Perfomance Statistics + * Read Subsystem Data - Performance Statistics */ typedef struct dasd_rssd_perf_stats_t { unsigned char invalid:1; diff --git a/include/asm-s390/ipl.h b/include/asm-s390/ipl.h index 2c40fd3a137f..c1b2e50392bb 100644 --- a/include/asm-s390/ipl.h +++ b/include/asm-s390/ipl.h @@ -83,6 +83,8 @@ extern u32 dump_prefix_page; extern unsigned int zfcpdump_prefix_array[]; extern void do_reipl(void); +extern void do_halt(void); +extern void do_poff(void); extern void ipl_save_parameters(void); enum { @@ -118,7 +120,7 @@ struct ipl_info }; extern struct ipl_info ipl_info; -extern void setup_ipl_info(void); +extern void setup_ipl(void); /* * DIAG 308 support @@ -141,6 +143,10 @@ enum diag308_opt { DIAG308_IPL_OPT_DUMP = 0x20, }; +enum diag308_flags { + DIAG308_FLAGS_LP_VALID = 0x80, +}; + enum diag308_rc { DIAG308_RC_OK = 1, }; diff --git a/include/asm-s390/mmu_context.h b/include/asm-s390/mmu_context.h index 05b842126b99..a77d4ba3c8eb 100644 --- a/include/asm-s390/mmu_context.h +++ b/include/asm-s390/mmu_context.h @@ -12,10 +12,15 @@ #include <asm/pgalloc.h> #include <asm-generic/mm_hooks.h> -/* - * get a new mmu context.. S390 don't know about contexts. - */ -#define init_new_context(tsk,mm) 0 +static inline int init_new_context(struct task_struct *tsk, + struct mm_struct *mm) +{ + mm->context = _ASCE_TABLE_LENGTH | _ASCE_USER_BITS; +#ifdef CONFIG_64BIT + mm->context |= _ASCE_TYPE_REGION3; +#endif + return 0; +} #define destroy_context(mm) do { } while (0) @@ -27,19 +32,11 @@ static inline void update_mm(struct mm_struct *mm, struct task_struct *tsk) { - pgd_t *pgd = mm->pgd; - unsigned long asce_bits; - - /* Calculate asce bits from the first pgd table entry. */ - asce_bits = _ASCE_TABLE_LENGTH | _ASCE_USER_BITS; -#ifdef CONFIG_64BIT - asce_bits |= _ASCE_TYPE_REGION3; -#endif - S390_lowcore.user_asce = asce_bits | __pa(pgd); + S390_lowcore.user_asce = mm->context | __pa(mm->pgd); if (switch_amode) { /* Load primary space page table origin. */ - pgd_t *shadow_pgd = get_shadow_table(pgd) ? : pgd; - S390_lowcore.user_exec_asce = asce_bits | __pa(shadow_pgd); + pgd_t *shadow_pgd = get_shadow_table(mm->pgd) ? : mm->pgd; + S390_lowcore.user_exec_asce = mm->context | __pa(shadow_pgd); asm volatile(LCTL_OPCODE" 1,1,%0\n" : : "m" (S390_lowcore.user_exec_asce) ); } else diff --git a/include/asm-s390/percpu.h b/include/asm-s390/percpu.h index 545857e64443..408d60b4f75b 100644 --- a/include/asm-s390/percpu.h +++ b/include/asm-s390/percpu.h @@ -4,8 +4,6 @@ #include <linux/compiler.h> #include <asm/lowcore.h> -#define __GENERIC_PER_CPU - /* * s390 uses its own implementation for per cpu data, the offset of * the cpu local data area is cached in the cpu's lowcore memory. @@ -15,67 +13,25 @@ */ #if defined(__s390x__) && defined(MODULE) -#define __reloc_hide(var,offset) (*({ \ +#define SHIFT_PERCPU_PTR(ptr,offset) (({ \ extern int simple_identifier_##var(void); \ unsigned long *__ptr; \ - asm ( "larl %0,per_cpu__"#var"@GOTENT" \ - : "=a" (__ptr) : "X" (per_cpu__##var) ); \ - (typeof(&per_cpu__##var))((*__ptr) + (offset)); })) + asm ( "larl %0, %1@GOTENT" \ + : "=a" (__ptr) : "X" (ptr) ); \ + (typeof(ptr))((*__ptr) + (offset)); })) #else -#define __reloc_hide(var, offset) (*({ \ +#define SHIFT_PERCPU_PTR(ptr, offset) (({ \ extern int simple_identifier_##var(void); \ unsigned long __ptr; \ - asm ( "" : "=a" (__ptr) : "0" (&per_cpu__##var) ); \ - (typeof(&per_cpu__##var)) (__ptr + (offset)); })) + asm ( "" : "=a" (__ptr) : "0" (ptr) ); \ + (typeof(ptr)) (__ptr + (offset)); })) #endif -#ifdef CONFIG_SMP - -extern unsigned long __per_cpu_offset[NR_CPUS]; - -/* Separate out the type, so (int[3], foo) works. */ -#define DEFINE_PER_CPU(type, name) \ - __attribute__((__section__(".data.percpu"))) \ - __typeof__(type) per_cpu__##name - -#define DEFINE_PER_CPU_SHARED_ALIGNED(type, name) \ - __attribute__((__section__(".data.percpu.shared_aligned"))) \ - __typeof__(type) per_cpu__##name \ - ____cacheline_aligned_in_smp - -#define __get_cpu_var(var) __reloc_hide(var,S390_lowcore.percpu_offset) -#define __raw_get_cpu_var(var) __reloc_hide(var,S390_lowcore.percpu_offset) -#define per_cpu(var,cpu) __reloc_hide(var,__per_cpu_offset[cpu]) -#define per_cpu_offset(x) (__per_cpu_offset[x]) - -/* A macro to avoid #include hell... */ -#define percpu_modcopy(pcpudst, src, size) \ -do { \ - unsigned int __i; \ - for_each_possible_cpu(__i) \ - memcpy((pcpudst)+__per_cpu_offset[__i], \ - (src), (size)); \ -} while (0) - -#else /* ! SMP */ - -#define DEFINE_PER_CPU(type, name) \ - __typeof__(type) per_cpu__##name -#define DEFINE_PER_CPU_SHARED_ALIGNED(type, name) \ - DEFINE_PER_CPU(type, name) - -#define __get_cpu_var(var) __reloc_hide(var,0) -#define __raw_get_cpu_var(var) __reloc_hide(var,0) -#define per_cpu(var,cpu) __reloc_hide(var,0) - -#endif /* SMP */ - -#define DECLARE_PER_CPU(type, name) extern __typeof__(type) per_cpu__##name +#define __my_cpu_offset S390_lowcore.percpu_offset -#define EXPORT_PER_CPU_SYMBOL(var) EXPORT_SYMBOL(per_cpu__##var) -#define EXPORT_PER_CPU_SYMBOL_GPL(var) EXPORT_SYMBOL_GPL(per_cpu__##var) +#include <asm-generic/percpu.h> #endif /* __ARCH_S390_PERCPU__ */ diff --git a/include/asm-s390/pgalloc.h b/include/asm-s390/pgalloc.h index 709dd1740956..6f6619ba8980 100644 --- a/include/asm-s390/pgalloc.h +++ b/include/asm-s390/pgalloc.h @@ -57,10 +57,10 @@ static inline unsigned long pgd_entry_type(struct mm_struct *mm) } #define pud_alloc_one(mm,address) ({ BUG(); ((pud_t *)2); }) -#define pud_free(x) do { } while (0) +#define pud_free(mm, x) do { } while (0) #define pmd_alloc_one(mm,address) ({ BUG(); ((pmd_t *)2); }) -#define pmd_free(x) do { } while (0) +#define pmd_free(mm, x) do { } while (0) #define pgd_populate(mm, pgd, pud) BUG() #define pgd_populate_kernel(mm, pgd, pud) BUG() @@ -76,7 +76,7 @@ static inline unsigned long pgd_entry_type(struct mm_struct *mm) } #define pud_alloc_one(mm,address) ({ BUG(); ((pud_t *)2); }) -#define pud_free(x) do { } while (0) +#define pud_free(mm, x) do { } while (0) static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long vmaddr) { @@ -85,7 +85,7 @@ static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long vmaddr) crst_table_init(crst, _SEGMENT_ENTRY_EMPTY); return (pmd_t *) crst; } -#define pmd_free(pmd) crst_table_free((unsigned long *) pmd) +#define pmd_free(mm, pmd) crst_table_free((unsigned long *)pmd) #define pgd_populate(mm, pgd, pud) BUG() #define pgd_populate_kernel(mm, pgd, pud) BUG() @@ -115,7 +115,7 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm) crst_table_init(crst, pgd_entry_type(mm)); return (pgd_t *) crst; } -#define pgd_free(pgd) crst_table_free((unsigned long *) pgd) +#define pgd_free(mm, pgd) crst_table_free((unsigned long *) pgd) static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, pte_t *pte) @@ -151,9 +151,9 @@ pmd_populate(struct mm_struct *mm, pmd_t *pmd, struct page *page) #define pte_alloc_one(mm, vmaddr) \ virt_to_page(page_table_alloc(s390_noexec)) -#define pte_free_kernel(pte) \ +#define pte_free_kernel(mm, pte) \ page_table_free((unsigned long *) pte) -#define pte_free(pte) \ +#define pte_free(mm, pte) \ page_table_free((unsigned long *) page_to_phys((struct page *) pte)) #endif /* _S390_PGALLOC_H */ diff --git a/include/asm-s390/pgtable.h b/include/asm-s390/pgtable.h index f2cc25b74adf..3f520754e71c 100644 --- a/include/asm-s390/pgtable.h +++ b/include/asm-s390/pgtable.h @@ -104,42 +104,34 @@ extern char empty_zero_page[PAGE_SIZE]; #ifndef __ASSEMBLY__ /* - * Just any arbitrary offset to the start of the vmalloc VM area: the - * current 8MB value just means that there will be a 8MB "hole" after the - * physical memory until the kernel virtual memory starts. That means that - * any out-of-bounds memory accesses will hopefully be caught. - * The vmalloc() routines leaves a hole of 4kB between each vmalloced - * area for the same reason. ;) - * vmalloc area starts at 4GB to prevent syscall table entry exchanging - * from modules. - */ -extern unsigned long vmalloc_end; - -#ifdef CONFIG_64BIT -#define VMALLOC_ADDR (max(0x100000000UL, (unsigned long) high_memory)) -#else -#define VMALLOC_ADDR ((unsigned long) high_memory) -#endif -#define VMALLOC_OFFSET (8*1024*1024) -#define VMALLOC_START ((VMALLOC_ADDR + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) -#define VMALLOC_END vmalloc_end - -/* - * We need some free virtual space to be able to do vmalloc. - * VMALLOC_MIN_SIZE defines the minimum size of the vmalloc - * area. On a machine with 2GB memory we make sure that we - * have at least 128MB free space for vmalloc. On a machine - * with 4TB we make sure we have at least 128GB. + * The vmalloc area will always be on the topmost area of the kernel + * mapping. We reserve 96MB (31bit) / 1GB (64bit) for vmalloc, + * which should be enough for any sane case. + * By putting vmalloc at the top, we maximise the gap between physical + * memory and vmalloc to catch misplaced memory accesses. As a side + * effect, this also makes sure that 64 bit module code cannot be used + * as system call address. */ #ifndef __s390x__ -#define VMALLOC_MIN_SIZE 0x8000000UL -#define VMALLOC_END_INIT 0x80000000UL +#define VMALLOC_START 0x78000000UL +#define VMALLOC_END 0x7e000000UL +#define VMEM_MAP_END 0x80000000UL #else /* __s390x__ */ -#define VMALLOC_MIN_SIZE 0x2000000000UL -#define VMALLOC_END_INIT 0x40000000000UL +#define VMALLOC_START 0x3e000000000UL +#define VMALLOC_END 0x3e040000000UL +#define VMEM_MAP_END 0x40000000000UL #endif /* __s390x__ */ /* + * VMEM_MAX_PHYS is the highest physical address that can be added to the 1:1 + * mapping. This needs to be calculated at compile time since the size of the + * VMEM_MAP is static but the size of struct page can change. + */ +#define VMEM_MAX_PHYS min(VMALLOC_START, ((VMEM_MAP_END - VMALLOC_END) / \ + sizeof(struct page) * PAGE_SIZE) & ~((16 << 20) - 1)) +#define VMEM_MAP ((struct page *) VMALLOC_END) + +/* * A 31 bit pagetable entry of S390 has following format: * | PFRA | | OS | * 0 0IP0 @@ -453,12 +445,12 @@ static inline int pgd_bad(pgd_t pgd) { return 0; } static inline int pud_present(pud_t pud) { - return pud_val(pud) & _REGION_ENTRY_ORIGIN; + return (pud_val(pud) & _REGION_ENTRY_ORIGIN) != 0UL; } static inline int pud_none(pud_t pud) { - return pud_val(pud) & _REGION_ENTRY_INV; + return (pud_val(pud) & _REGION_ENTRY_INV) != 0UL; } static inline int pud_bad(pud_t pud) @@ -471,12 +463,12 @@ static inline int pud_bad(pud_t pud) static inline int pmd_present(pmd_t pmd) { - return pmd_val(pmd) & _SEGMENT_ENTRY_ORIGIN; + return (pmd_val(pmd) & _SEGMENT_ENTRY_ORIGIN) != 0UL; } static inline int pmd_none(pmd_t pmd) { - return pmd_val(pmd) & _SEGMENT_ENTRY_INV; + return (pmd_val(pmd) & _SEGMENT_ENTRY_INV) != 0UL; } static inline int pmd_bad(pmd_t pmd) diff --git a/include/asm-s390/processor.h b/include/asm-s390/processor.h index 21d40a19355e..4f744609cd11 100644 --- a/include/asm-s390/processor.h +++ b/include/asm-s390/processor.h @@ -59,9 +59,6 @@ extern void s390_adjust_jiffies(void); extern void print_cpu_info(struct cpuinfo_S390 *); extern int get_cpu_capability(unsigned int *); -/* Lazy FPU handling on uni-processor */ -extern struct task_struct *last_task_used_math; - /* * User space process size: 2GB for 31 bit, 4TB for 64 bit. */ @@ -73,8 +70,9 @@ extern struct task_struct *last_task_used_math; #else /* __s390x__ */ -# define TASK_SIZE (test_thread_flag(TIF_31BIT) ? \ +# define TASK_SIZE_OF(tsk) (test_tsk_thread_flag(tsk, TIF_31BIT) ? \ (0x80000000UL) : (0x40000000000UL)) +# define TASK_SIZE TASK_SIZE_OF(current) # define TASK_UNMAPPED_BASE (TASK_SIZE / 2) # define DEFAULT_TASK_SIZE (0x40000000000UL) @@ -95,7 +93,6 @@ struct thread_struct { unsigned long ksp; /* kernel stack pointer */ mm_segment_t mm_segment; unsigned long prot_addr; /* address of protection-excep. */ - unsigned int error_code; /* error-code of last prog-excep. */ unsigned int trap_no; per_struct per_info; /* Used to give failing instruction back to user for ieee exceptions */ diff --git a/include/asm-s390/ptrace.h b/include/asm-s390/ptrace.h index 332ee73688fc..61f6952f2e35 100644 --- a/include/asm-s390/ptrace.h +++ b/include/asm-s390/ptrace.h @@ -465,6 +465,14 @@ struct user_regs_struct #ifdef __KERNEL__ #define __ARCH_SYS_PTRACE 1 +/* + * These are defined as per linux/ptrace.h, which see. + */ +#define arch_has_single_step() (1) +struct task_struct; +extern void user_enable_single_step(struct task_struct *); +extern void user_disable_single_step(struct task_struct *); + #define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0) #define instruction_pointer(regs) ((regs)->psw.addr & PSW_ADDR_INSN) #define regs_return_value(regs)((regs)->gprs[2]) diff --git a/include/asm-s390/qdio.h b/include/asm-s390/qdio.h index 74db1dc10a7d..4b8ff55f680e 100644 --- a/include/asm-s390/qdio.h +++ b/include/asm-s390/qdio.h @@ -184,7 +184,7 @@ struct qdr { #endif /* QDIO_32_BIT */ unsigned long qiba; /* queue-information-block address */ unsigned int res8; /* reserved */ - unsigned int qkey : 4; /* queue-informatio-block key */ + unsigned int qkey : 4; /* queue-information-block key */ unsigned int res9 : 28; /* reserved */ /* union _qd {*/ /* why this? */ struct qdesfmt0 qdf0[126]; diff --git a/include/asm-s390/rwsem.h b/include/asm-s390/rwsem.h index 90f4eccaa290..9d2a17971805 100644 --- a/include/asm-s390/rwsem.h +++ b/include/asm-s390/rwsem.h @@ -91,8 +91,8 @@ struct rw_semaphore { #endif #define __RWSEM_INITIALIZER(name) \ -{ RWSEM_UNLOCKED_VALUE, SPIN_LOCK_UNLOCKED, LIST_HEAD_INIT((name).wait_list) \ - __RWSEM_DEP_MAP_INIT(name) } + { RWSEM_UNLOCKED_VALUE, __SPIN_LOCK_UNLOCKED((name).wait.lock), \ + LIST_HEAD_INIT((name).wait_list) __RWSEM_DEP_MAP_INIT(name) } #define DECLARE_RWSEM(name) \ struct rw_semaphore name = __RWSEM_INITIALIZER(name) diff --git a/include/asm-s390/sclp.h b/include/asm-s390/sclp.h index cb9faf1ea5cf..b5f2843013a3 100644 --- a/include/asm-s390/sclp.h +++ b/include/asm-s390/sclp.h @@ -27,7 +27,25 @@ struct sclp_ipl_info { char loadparm[LOADPARM_LEN]; }; -void sclp_readinfo_early(void); +struct sclp_cpu_entry { + u8 address; + u8 reserved0[13]; + u8 type; + u8 reserved1; +} __attribute__((packed)); + +struct sclp_cpu_info { + unsigned int configured; + unsigned int standby; + unsigned int combined; + int has_cpu_type; + struct sclp_cpu_entry cpu[255]; +}; + +int sclp_get_cpu_info(struct sclp_cpu_info *info); +int sclp_cpu_configure(u8 cpu); +int sclp_cpu_deconfigure(u8 cpu); +void sclp_read_info_early(void); void sclp_facilities_detect(void); unsigned long long sclp_memory_detect(void); int sclp_sdias_blk_count(void); diff --git a/include/asm-s390/smp.h b/include/asm-s390/smp.h index 07708c07701e..c7b74326a527 100644 --- a/include/asm-s390/smp.h +++ b/include/asm-s390/smp.h @@ -35,8 +35,6 @@ extern void machine_restart_smp(char *); extern void machine_halt_smp(void); extern void machine_power_off_smp(void); -extern void smp_setup_cpu_possible_map(void); - #define NO_PROC_ID 0xFF /* No processor magic marker */ /* @@ -92,6 +90,8 @@ extern void __cpu_die (unsigned int cpu); extern void cpu_die (void) __attribute__ ((noreturn)); extern int __cpu_up (unsigned int cpu); +extern int smp_call_function_mask(cpumask_t mask, void (*func)(void *), + void *info, int wait); #endif #ifndef CONFIG_SMP @@ -103,7 +103,6 @@ static inline void smp_send_stop(void) #define hard_smp_processor_id() 0 #define smp_cpu_not_running(cpu) 1 -#define smp_setup_cpu_possible_map() do { } while (0) #endif extern union save_area *zfcpdump_save_areas[NR_CPUS + 1]; diff --git a/include/asm-s390/socket.h b/include/asm-s390/socket.h index 1161ebe3dec9..c786ab623b2d 100644 --- a/include/asm-s390/socket.h +++ b/include/asm-s390/socket.h @@ -60,4 +60,6 @@ #define SO_TIMESTAMPNS 35 #define SCM_TIMESTAMPNS SO_TIMESTAMPNS +#define SO_MARK 36 + #endif /* _ASM_SOCKET_H */ diff --git a/include/asm-s390/spinlock.h b/include/asm-s390/spinlock.h index 3fd43826fd0b..df84ae96915f 100644 --- a/include/asm-s390/spinlock.h +++ b/include/asm-s390/spinlock.h @@ -53,44 +53,48 @@ _raw_compare_and_swap(volatile unsigned int *lock, */ #define __raw_spin_is_locked(x) ((x)->owner_cpu != 0) -#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock) #define __raw_spin_unlock_wait(lock) \ do { while (__raw_spin_is_locked(lock)) \ _raw_spin_relax(lock); } while (0) -extern void _raw_spin_lock_wait(raw_spinlock_t *, unsigned int pc); -extern int _raw_spin_trylock_retry(raw_spinlock_t *, unsigned int pc); +extern void _raw_spin_lock_wait(raw_spinlock_t *); +extern void _raw_spin_lock_wait_flags(raw_spinlock_t *, unsigned long flags); +extern int _raw_spin_trylock_retry(raw_spinlock_t *); extern void _raw_spin_relax(raw_spinlock_t *lock); static inline void __raw_spin_lock(raw_spinlock_t *lp) { - unsigned long pc = 1 | (unsigned long) __builtin_return_address(0); int old; old = _raw_compare_and_swap(&lp->owner_cpu, 0, ~smp_processor_id()); - if (likely(old == 0)) { - lp->owner_pc = pc; + if (likely(old == 0)) return; - } - _raw_spin_lock_wait(lp, pc); + _raw_spin_lock_wait(lp); +} + +static inline void __raw_spin_lock_flags(raw_spinlock_t *lp, + unsigned long flags) +{ + int old; + + old = _raw_compare_and_swap(&lp->owner_cpu, 0, ~smp_processor_id()); + if (likely(old == 0)) + return; + _raw_spin_lock_wait_flags(lp, flags); } static inline int __raw_spin_trylock(raw_spinlock_t *lp) { - unsigned long pc = 1 | (unsigned long) __builtin_return_address(0); int old; old = _raw_compare_and_swap(&lp->owner_cpu, 0, ~smp_processor_id()); - if (likely(old == 0)) { - lp->owner_pc = pc; + if (likely(old == 0)) return 1; - } - return _raw_spin_trylock_retry(lp, pc); + return _raw_spin_trylock_retry(lp); } static inline void __raw_spin_unlock(raw_spinlock_t *lp) { - lp->owner_pc = 0; _raw_compare_and_swap(&lp->owner_cpu, lp->owner_cpu, 0); } diff --git a/include/asm-s390/spinlock_types.h b/include/asm-s390/spinlock_types.h index b7ac13f7aa37..654abc40de04 100644 --- a/include/asm-s390/spinlock_types.h +++ b/include/asm-s390/spinlock_types.h @@ -7,7 +7,6 @@ typedef struct { volatile unsigned int owner_cpu; - volatile unsigned int owner_pc; } __attribute__ ((aligned (4))) raw_spinlock_t; #define __RAW_SPIN_LOCK_UNLOCKED { 0 } diff --git a/include/asm-s390/system.h b/include/asm-s390/system.h index d866d3385556..44bda786eef7 100644 --- a/include/asm-s390/system.h +++ b/include/asm-s390/system.h @@ -388,6 +388,11 @@ extern void (*_machine_power_off)(void); #define arch_align_stack(x) (x) +#ifdef CONFIG_TRACE_IRQFLAGS +extern psw_t sysc_restore_trace_psw; +extern psw_t io_restore_trace_psw; +#endif + #endif /* __KERNEL__ */ #endif diff --git a/include/asm-s390/tlb.h b/include/asm-s390/tlb.h index 618693cfc10f..985de2b88279 100644 --- a/include/asm-s390/tlb.h +++ b/include/asm-s390/tlb.h @@ -65,9 +65,9 @@ static inline void tlb_flush_mmu(struct mmu_gather *tlb, if (!tlb->fullmm && (tlb->nr_ptes > 0 || tlb->nr_pmds < TLB_NR_PTRS)) __tlb_flush_mm(tlb->mm); while (tlb->nr_ptes > 0) - pte_free(tlb->array[--tlb->nr_ptes]); + pte_free(tlb->mm, tlb->array[--tlb->nr_ptes]); while (tlb->nr_pmds < TLB_NR_PTRS) - pmd_free((pmd_t *) tlb->array[tlb->nr_pmds++]); + pmd_free(tlb->mm, (pmd_t *) tlb->array[tlb->nr_pmds++]); } static inline void tlb_finish_mmu(struct mmu_gather *tlb, @@ -102,7 +102,7 @@ static inline void pte_free_tlb(struct mmu_gather *tlb, struct page *page) if (tlb->nr_ptes >= tlb->nr_pmds) tlb_flush_mmu(tlb, 0, 0); } else - pte_free(page); + pte_free(tlb->mm, page); } /* @@ -117,7 +117,7 @@ static inline void pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd) if (tlb->nr_ptes >= tlb->nr_pmds) tlb_flush_mmu(tlb, 0, 0); } else - pmd_free(pmd); + pmd_free(tlb->mm, pmd); #endif } diff --git a/include/asm-s390/tlbflush.h b/include/asm-s390/tlbflush.h index a69bd2490d52..70fa5ae58180 100644 --- a/include/asm-s390/tlbflush.h +++ b/include/asm-s390/tlbflush.h @@ -42,11 +42,11 @@ static inline void __tlb_flush_global(void) /* * Flush all tlb entries of a page table on all cpus. */ -static inline void __tlb_flush_idte(pgd_t *pgd) +static inline void __tlb_flush_idte(unsigned long asce) { asm volatile( " .insn rrf,0xb98e0000,0,%0,%1,0" - : : "a" (2048), "a" (__pa(pgd) & PAGE_MASK) : "cc" ); + : : "a" (2048), "a" (asce) : "cc" ); } static inline void __tlb_flush_mm(struct mm_struct * mm) @@ -61,11 +61,11 @@ static inline void __tlb_flush_mm(struct mm_struct * mm) * only ran on the local cpu. */ if (MACHINE_HAS_IDTE) { - pgd_t *shadow_pgd = get_shadow_table(mm->pgd); + pgd_t *shadow = get_shadow_table(mm->pgd); - if (shadow_pgd) - __tlb_flush_idte(shadow_pgd); - __tlb_flush_idte(mm->pgd); + if (shadow) + __tlb_flush_idte((unsigned long) shadow | mm->context); + __tlb_flush_idte((unsigned long) mm->pgd | mm->context); return; } preempt_disable(); @@ -106,9 +106,23 @@ static inline void __tlb_flush_mm_cond(struct mm_struct * mm) */ #define flush_tlb() do { } while (0) #define flush_tlb_all() do { } while (0) -#define flush_tlb_mm(mm) __tlb_flush_mm_cond(mm) #define flush_tlb_page(vma, addr) do { } while (0) -#define flush_tlb_range(vma, start, end) __tlb_flush_mm_cond(mm) -#define flush_tlb_kernel_range(start, end) __tlb_flush_mm(&init_mm) + +static inline void flush_tlb_mm(struct mm_struct *mm) +{ + __tlb_flush_mm_cond(mm); +} + +static inline void flush_tlb_range(struct vm_area_struct *vma, + unsigned long start, unsigned long end) +{ + __tlb_flush_mm_cond(vma->vm_mm); +} + +static inline void flush_tlb_kernel_range(unsigned long start, + unsigned long end) +{ + __tlb_flush_mm(&init_mm); +} #endif /* _S390_TLBFLUSH_H */ diff --git a/include/asm-s390/zcrypt.h b/include/asm-s390/zcrypt.h index a5dada617751..f228f1b86877 100644 --- a/include/asm-s390/zcrypt.h +++ b/include/asm-s390/zcrypt.h @@ -117,7 +117,7 @@ struct CPRBX { unsigned char padx004[16 - sizeof (char *)]; unsigned char * req_extb; /* request extension block 'addr'*/ unsigned char padx005[16 - sizeof (char *)]; - unsigned char * rpl_extb; /* reply extension block 'addres'*/ + unsigned char * rpl_extb; /* reply extension block 'address'*/ unsigned short ccp_rtcode; /* server return code */ unsigned short ccp_rscode; /* server reason code */ unsigned int mac_data_len; /* Mac Data Length */ |