aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-s390
diff options
context:
space:
mode:
Diffstat (limited to 'include/asm-s390')
-rw-r--r--include/asm-s390/checksum.h45
-rw-r--r--include/asm-s390/device.h7
-rw-r--r--include/asm-s390/pgtable.h50
-rw-r--r--include/asm-s390/unistd.h3
4 files changed, 70 insertions, 35 deletions
diff --git a/include/asm-s390/checksum.h b/include/asm-s390/checksum.h
index 37c362d89fad..0a3cd7ec8451 100644
--- a/include/asm-s390/checksum.h
+++ b/include/asm-s390/checksum.h
@@ -27,8 +27,8 @@
27 * 27 *
28 * it's best to have buff aligned on a 32-bit boundary 28 * it's best to have buff aligned on a 32-bit boundary
29 */ 29 */
30static inline unsigned int 30static inline __wsum
31csum_partial(const unsigned char * buff, int len, unsigned int sum) 31csum_partial(const void *buff, int len, __wsum sum)
32{ 32{
33 register unsigned long reg2 asm("2") = (unsigned long) buff; 33 register unsigned long reg2 asm("2") = (unsigned long) buff;
34 register unsigned long reg3 asm("3") = (unsigned long) len; 34 register unsigned long reg3 asm("3") = (unsigned long) len;
@@ -49,9 +49,9 @@ csum_partial(const unsigned char * buff, int len, unsigned int sum)
49 * Copy from userspace and compute checksum. If we catch an exception 49 * Copy from userspace and compute checksum. If we catch an exception
50 * then zero the rest of the buffer. 50 * then zero the rest of the buffer.
51 */ 51 */
52static inline unsigned int 52static inline __wsum
53csum_partial_copy_from_user(const char __user *src, char *dst, 53csum_partial_copy_from_user(const void __user *src, void *dst,
54 int len, unsigned int sum, 54 int len, __wsum sum,
55 int *err_ptr) 55 int *err_ptr)
56{ 56{
57 int missing; 57 int missing;
@@ -66,8 +66,8 @@ csum_partial_copy_from_user(const char __user *src, char *dst,
66} 66}
67 67
68 68
69static inline unsigned int 69static inline __wsum
70csum_partial_copy_nocheck (const char *src, char *dst, int len, unsigned int sum) 70csum_partial_copy_nocheck (const void *src, void *dst, int len, __wsum sum)
71{ 71{
72 memcpy(dst,src,len); 72 memcpy(dst,src,len);
73 return csum_partial(dst, len, sum); 73 return csum_partial(dst, len, sum);
@@ -76,8 +76,7 @@ csum_partial_copy_nocheck (const char *src, char *dst, int len, unsigned int sum
76/* 76/*
77 * Fold a partial checksum without adding pseudo headers 77 * Fold a partial checksum without adding pseudo headers
78 */ 78 */
79static inline unsigned short 79static inline __sum16 csum_fold(__wsum sum)
80csum_fold(unsigned int sum)
81{ 80{
82#ifndef __s390x__ 81#ifndef __s390x__
83 register_pair rp; 82 register_pair rp;
@@ -100,7 +99,7 @@ csum_fold(unsigned int sum)
100 " srl %0,16\n" /* %0 = H+L+C */ 99 " srl %0,16\n" /* %0 = H+L+C */
101 : "+&d" (sum) : : "cc", "2", "3"); 100 : "+&d" (sum) : : "cc", "2", "3");
102#endif /* __s390x__ */ 101#endif /* __s390x__ */
103 return ((unsigned short) ~sum); 102 return (__force __sum16) ~sum;
104} 103}
105 104
106/* 105/*
@@ -108,8 +107,7 @@ csum_fold(unsigned int sum)
108 * which always checksum on 4 octet boundaries. 107 * which always checksum on 4 octet boundaries.
109 * 108 *
110 */ 109 */
111static inline unsigned short 110static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
112ip_fast_csum(unsigned char *iph, unsigned int ihl)
113{ 111{
114 return csum_fold(csum_partial(iph, ihl*4, 0)); 112 return csum_fold(csum_partial(iph, ihl*4, 0));
115} 113}
@@ -118,10 +116,10 @@ ip_fast_csum(unsigned char *iph, unsigned int ihl)
118 * computes the checksum of the TCP/UDP pseudo-header 116 * computes the checksum of the TCP/UDP pseudo-header
119 * returns a 32-bit checksum 117 * returns a 32-bit checksum
120 */ 118 */
121static inline unsigned int 119static inline __wsum
122csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr, 120csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
123 unsigned short len, unsigned short proto, 121 unsigned short len, unsigned short proto,
124 unsigned int sum) 122 __wsum sum)
125{ 123{
126#ifndef __s390x__ 124#ifndef __s390x__
127 asm volatile( 125 asm volatile(
@@ -137,12 +135,12 @@ csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr,
137 "1:" 135 "1:"
138 : "+&d" (sum) : "d" (daddr) : "cc"); 136 : "+&d" (sum) : "d" (daddr) : "cc");
139 asm volatile( 137 asm volatile(
140 " alr %0,%1\n" /* sum += (len<<16) + (proto<<8) */ 138 " alr %0,%1\n" /* sum += len + proto */
141 " brc 12,2f\n" 139 " brc 12,2f\n"
142 " ahi %0,1\n" /* add carry */ 140 " ahi %0,1\n" /* add carry */
143 "2:" 141 "2:"
144 : "+&d" (sum) 142 : "+&d" (sum)
145 : "d" (((unsigned int) len<<16) + (unsigned int) proto) 143 : "d" (len + proto)
146 : "cc"); 144 : "cc");
147#else /* __s390x__ */ 145#else /* __s390x__ */
148 asm volatile( 146 asm volatile(
@@ -153,7 +151,7 @@ csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr,
153 "0: algr %0,%2\n" /* sum += daddr */ 151 "0: algr %0,%2\n" /* sum += daddr */
154 " brc 12,1f\n" 152 " brc 12,1f\n"
155 " aghi %0,1\n" /* add carry */ 153 " aghi %0,1\n" /* add carry */
156 "1: algfr %0,%3\n" /* sum += (len<<16) + proto */ 154 "1: algfr %0,%3\n" /* sum += len + proto */
157 " brc 12,2f\n" 155 " brc 12,2f\n"
158 " aghi %0,1\n" /* add carry */ 156 " aghi %0,1\n" /* add carry */
159 "2: srlg 0,%0,32\n" 157 "2: srlg 0,%0,32\n"
@@ -163,7 +161,7 @@ csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr,
163 "3: llgfr %0,%0" 161 "3: llgfr %0,%0"
164 : "+&d" (sum) 162 : "+&d" (sum)
165 : "d" (saddr), "d" (daddr), 163 : "d" (saddr), "d" (daddr),
166 "d" (((unsigned int) len<<16) + (unsigned int) proto) 164 "d" (len + proto)
167 : "cc", "0"); 165 : "cc", "0");
168#endif /* __s390x__ */ 166#endif /* __s390x__ */
169 return sum; 167 return sum;
@@ -174,10 +172,10 @@ csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr,
174 * returns a 16-bit checksum, already complemented 172 * returns a 16-bit checksum, already complemented
175 */ 173 */
176 174
177static inline unsigned short int 175static inline __sum16
178csum_tcpudp_magic(unsigned long saddr, unsigned long daddr, 176csum_tcpudp_magic(__be32 saddr, __be32 daddr,
179 unsigned short len, unsigned short proto, 177 unsigned short len, unsigned short proto,
180 unsigned int sum) 178 __wsum sum)
181{ 179{
182 return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); 180 return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
183} 181}
@@ -187,8 +185,7 @@ csum_tcpudp_magic(unsigned long saddr, unsigned long daddr,
187 * in icmp.c 185 * in icmp.c
188 */ 186 */
189 187
190static inline unsigned short 188static inline __sum16 ip_compute_csum(const void *buff, int len)
191ip_compute_csum(unsigned char * buff, int len)
192{ 189{
193 return csum_fold(csum_partial(buff, len, 0)); 190 return csum_fold(csum_partial(buff, len, 0));
194} 191}
diff --git a/include/asm-s390/device.h b/include/asm-s390/device.h
new file mode 100644
index 000000000000..d8f9872b0e2d
--- /dev/null
+++ b/include/asm-s390/device.h
@@ -0,0 +1,7 @@
1/*
2 * Arch specific extensions to struct device
3 *
4 * This file is released under the GPLv2
5 */
6#include <asm-generic/device.h>
7
diff --git a/include/asm-s390/pgtable.h b/include/asm-s390/pgtable.h
index 519f0a5ff181..36bb6dacf008 100644
--- a/include/asm-s390/pgtable.h
+++ b/include/asm-s390/pgtable.h
@@ -200,18 +200,45 @@ extern char empty_zero_page[PAGE_SIZE];
200 */ 200 */
201 201
202/* Hardware bits in the page table entry */ 202/* Hardware bits in the page table entry */
203#define _PAGE_RO 0x200 /* HW read-only */ 203#define _PAGE_RO 0x200 /* HW read-only bit */
204#define _PAGE_INVALID 0x400 /* HW invalid */ 204#define _PAGE_INVALID 0x400 /* HW invalid bit */
205#define _PAGE_SWT 0x001 /* SW pte type bit t */
206#define _PAGE_SWX 0x002 /* SW pte type bit x */
205 207
206/* Mask and six different types of pages. */ 208/* Six different types of pages. */
207#define _PAGE_TYPE_MASK 0x601
208#define _PAGE_TYPE_EMPTY 0x400 209#define _PAGE_TYPE_EMPTY 0x400
209#define _PAGE_TYPE_NONE 0x401 210#define _PAGE_TYPE_NONE 0x401
210#define _PAGE_TYPE_SWAP 0x600 211#define _PAGE_TYPE_SWAP 0x403
211#define _PAGE_TYPE_FILE 0x601 212#define _PAGE_TYPE_FILE 0x601 /* bit 0x002 is used for offset !! */
212#define _PAGE_TYPE_RO 0x200 213#define _PAGE_TYPE_RO 0x200
213#define _PAGE_TYPE_RW 0x000 214#define _PAGE_TYPE_RW 0x000
214 215
216/*
217 * PTE type bits are rather complicated. handle_pte_fault uses pte_present,
218 * pte_none and pte_file to find out the pte type WITHOUT holding the page
219 * table lock. ptep_clear_flush on the other hand uses ptep_clear_flush to
220 * invalidate a given pte. ipte sets the hw invalid bit and clears all tlbs
221 * for the page. The page table entry is set to _PAGE_TYPE_EMPTY afterwards.
222 * This change is done while holding the lock, but the intermediate step
223 * of a previously valid pte with the hw invalid bit set can be observed by
224 * handle_pte_fault. That makes it necessary that all valid pte types with
225 * the hw invalid bit set must be distinguishable from the four pte types
226 * empty, none, swap and file.
227 *
228 * irxt ipte irxt
229 * _PAGE_TYPE_EMPTY 1000 -> 1000
230 * _PAGE_TYPE_NONE 1001 -> 1001
231 * _PAGE_TYPE_SWAP 1011 -> 1011
232 * _PAGE_TYPE_FILE 11?1 -> 11?1
233 * _PAGE_TYPE_RO 0100 -> 1100
234 * _PAGE_TYPE_RW 0000 -> 1000
235 *
236 * pte_none is true for bits combinations 1000, 1100
237 * pte_present is true for bits combinations 0000, 0010, 0100, 0110, 1001
238 * pte_file is true for bits combinations 1101, 1111
239 * swap pte is 1011 and 0001, 0011, 0101, 0111, 1010 and 1110 are invalid.
240 */
241
215#ifndef __s390x__ 242#ifndef __s390x__
216 243
217/* Bits in the segment table entry */ 244/* Bits in the segment table entry */
@@ -365,18 +392,21 @@ static inline int pmd_bad(pmd_t pmd)
365 392
366static inline int pte_none(pte_t pte) 393static inline int pte_none(pte_t pte)
367{ 394{
368 return (pte_val(pte) & _PAGE_TYPE_MASK) == _PAGE_TYPE_EMPTY; 395 return (pte_val(pte) & _PAGE_INVALID) && !(pte_val(pte) & _PAGE_SWT);
369} 396}
370 397
371static inline int pte_present(pte_t pte) 398static inline int pte_present(pte_t pte)
372{ 399{
373 return !(pte_val(pte) & _PAGE_INVALID) || 400 unsigned long mask = _PAGE_RO | _PAGE_INVALID | _PAGE_SWT | _PAGE_SWX;
374 (pte_val(pte) & _PAGE_TYPE_MASK) == _PAGE_TYPE_NONE; 401 return (pte_val(pte) & mask) == _PAGE_TYPE_NONE ||
402 (!(pte_val(pte) & _PAGE_INVALID) &&
403 !(pte_val(pte) & _PAGE_SWT));
375} 404}
376 405
377static inline int pte_file(pte_t pte) 406static inline int pte_file(pte_t pte)
378{ 407{
379 return (pte_val(pte) & _PAGE_TYPE_MASK) == _PAGE_TYPE_FILE; 408 unsigned long mask = _PAGE_RO | _PAGE_INVALID | _PAGE_SWT;
409 return (pte_val(pte) & mask) == _PAGE_TYPE_FILE;
380} 410}
381 411
382#define pte_same(a,b) (pte_val(a) == pte_val(b)) 412#define pte_same(a,b) (pte_val(a) == pte_val(b))
diff --git a/include/asm-s390/unistd.h b/include/asm-s390/unistd.h
index a19238cbcffa..71d3c21b84f0 100644
--- a/include/asm-s390/unistd.h
+++ b/include/asm-s390/unistd.h
@@ -249,8 +249,9 @@
249#define __NR_vmsplice 309 249#define __NR_vmsplice 309
250/* Number 310 is reserved for new sys_move_pages */ 250/* Number 310 is reserved for new sys_move_pages */
251#define __NR_getcpu 311 251#define __NR_getcpu 311
252#define __NR_epoll_pwait 312
252 253
253#define NR_syscalls 312 254#define NR_syscalls 313
254 255
255/* 256/*
256 * There are some system calls that are not present on 64 bit, some 257 * There are some system calls that are not present on 64 bit, some