diff options
Diffstat (limited to 'arch/s390')
49 files changed, 1607 insertions, 812 deletions
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 2ae5d72f47ed..e030e86ff6a3 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig | |||
@@ -95,7 +95,6 @@ config S390 | |||
95 | select HAVE_ARCH_TRACEHOOK | 95 | select HAVE_ARCH_TRACEHOOK |
96 | select INIT_ALL_POSSIBLE | 96 | select INIT_ALL_POSSIBLE |
97 | select HAVE_PERF_COUNTERS | 97 | select HAVE_PERF_COUNTERS |
98 | select GENERIC_ATOMIC64 if !64BIT | ||
99 | 98 | ||
100 | config SCHED_OMIT_FRAME_POINTER | 99 | config SCHED_OMIT_FRAME_POINTER |
101 | bool | 100 | bool |
@@ -481,13 +480,6 @@ config CMM_IUCV | |||
481 | Select this option to enable the special message interface to | 480 | Select this option to enable the special message interface to |
482 | the cooperative memory management. | 481 | the cooperative memory management. |
483 | 482 | ||
484 | config PAGE_STATES | ||
485 | bool "Unused page notification" | ||
486 | help | ||
487 | This enables the notification of unused pages to the | ||
488 | hypervisor. The ESSA instruction is used to do the states | ||
489 | changes between a page that has content and the unused state. | ||
490 | |||
491 | config APPLDATA_BASE | 483 | config APPLDATA_BASE |
492 | bool "Linux - VM Monitor Stream, base infrastructure" | 484 | bool "Linux - VM Monitor Stream, base infrastructure" |
493 | depends on PROC_FS | 485 | depends on PROC_FS |
diff --git a/arch/s390/Makefile b/arch/s390/Makefile index 0ff387cebf88..fc8fb20e7fc0 100644 --- a/arch/s390/Makefile +++ b/arch/s390/Makefile | |||
@@ -88,8 +88,7 @@ LDFLAGS_vmlinux := -e start | |||
88 | head-y := arch/s390/kernel/head.o arch/s390/kernel/init_task.o | 88 | head-y := arch/s390/kernel/head.o arch/s390/kernel/init_task.o |
89 | 89 | ||
90 | core-y += arch/s390/mm/ arch/s390/kernel/ arch/s390/crypto/ \ | 90 | core-y += arch/s390/mm/ arch/s390/kernel/ arch/s390/crypto/ \ |
91 | arch/s390/appldata/ arch/s390/hypfs/ arch/s390/kvm/ \ | 91 | arch/s390/appldata/ arch/s390/hypfs/ arch/s390/kvm/ |
92 | arch/s390/power/ | ||
93 | 92 | ||
94 | libs-y += arch/s390/lib/ | 93 | libs-y += arch/s390/lib/ |
95 | drivers-y += drivers/s390/ | 94 | drivers-y += drivers/s390/ |
diff --git a/arch/s390/hypfs/inode.c b/arch/s390/hypfs/inode.c index 5a805df216bb..bd9914b89488 100644 --- a/arch/s390/hypfs/inode.c +++ b/arch/s390/hypfs/inode.c | |||
@@ -355,11 +355,7 @@ static struct dentry *hypfs_create_file(struct super_block *sb, | |||
355 | { | 355 | { |
356 | struct dentry *dentry; | 356 | struct dentry *dentry; |
357 | struct inode *inode; | 357 | struct inode *inode; |
358 | struct qstr qname; | ||
359 | 358 | ||
360 | qname.name = name; | ||
361 | qname.len = strlen(name); | ||
362 | qname.hash = full_name_hash(name, qname.len); | ||
363 | mutex_lock(&parent->d_inode->i_mutex); | 359 | mutex_lock(&parent->d_inode->i_mutex); |
364 | dentry = lookup_one_len(name, parent, strlen(name)); | 360 | dentry = lookup_one_len(name, parent, strlen(name)); |
365 | if (IS_ERR(dentry)) { | 361 | if (IS_ERR(dentry)) { |
@@ -426,7 +422,7 @@ struct dentry *hypfs_create_u64(struct super_block *sb, struct dentry *dir, | |||
426 | char tmp[TMP_SIZE]; | 422 | char tmp[TMP_SIZE]; |
427 | struct dentry *dentry; | 423 | struct dentry *dentry; |
428 | 424 | ||
429 | snprintf(tmp, TMP_SIZE, "%lld\n", (unsigned long long int)value); | 425 | snprintf(tmp, TMP_SIZE, "%llu\n", (unsigned long long int)value); |
430 | buffer = kstrdup(tmp, GFP_KERNEL); | 426 | buffer = kstrdup(tmp, GFP_KERNEL); |
431 | if (!buffer) | 427 | if (!buffer) |
432 | return ERR_PTR(-ENOMEM); | 428 | return ERR_PTR(-ENOMEM); |
diff --git a/arch/s390/include/asm/atomic.h b/arch/s390/include/asm/atomic.h index c7d0abfb0f00..ae7c8f9f94a5 100644 --- a/arch/s390/include/asm/atomic.h +++ b/arch/s390/include/asm/atomic.h | |||
@@ -1,33 +1,23 @@ | |||
1 | #ifndef __ARCH_S390_ATOMIC__ | 1 | #ifndef __ARCH_S390_ATOMIC__ |
2 | #define __ARCH_S390_ATOMIC__ | 2 | #define __ARCH_S390_ATOMIC__ |
3 | 3 | ||
4 | #include <linux/compiler.h> | ||
5 | #include <linux/types.h> | ||
6 | |||
7 | /* | 4 | /* |
8 | * include/asm-s390/atomic.h | 5 | * Copyright 1999,2009 IBM Corp. |
6 | * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>, | ||
7 | * Denis Joseph Barrow, | ||
8 | * Arnd Bergmann <arndb@de.ibm.com>, | ||
9 | * | 9 | * |
10 | * S390 version | 10 | * Atomic operations that C can't guarantee us. |
11 | * Copyright (C) 1999-2005 IBM Deutschland Entwicklung GmbH, IBM Corporation | 11 | * Useful for resource counting etc. |
12 | * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), | 12 | * s390 uses 'Compare And Swap' for atomicity in SMP enviroment. |
13 | * Denis Joseph Barrow, | ||
14 | * Arnd Bergmann (arndb@de.ibm.com) | ||
15 | * | ||
16 | * Derived from "include/asm-i386/bitops.h" | ||
17 | * Copyright (C) 1992, Linus Torvalds | ||
18 | * | 13 | * |
19 | */ | 14 | */ |
20 | 15 | ||
21 | /* | 16 | #include <linux/compiler.h> |
22 | * Atomic operations that C can't guarantee us. Useful for | 17 | #include <linux/types.h> |
23 | * resource counting etc.. | ||
24 | * S390 uses 'Compare And Swap' for atomicity in SMP enviroment | ||
25 | */ | ||
26 | 18 | ||
27 | #define ATOMIC_INIT(i) { (i) } | 19 | #define ATOMIC_INIT(i) { (i) } |
28 | 20 | ||
29 | #ifdef __KERNEL__ | ||
30 | |||
31 | #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) | 21 | #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) |
32 | 22 | ||
33 | #define __CS_LOOP(ptr, op_val, op_string) ({ \ | 23 | #define __CS_LOOP(ptr, op_val, op_string) ({ \ |
@@ -77,7 +67,7 @@ static inline void atomic_set(atomic_t *v, int i) | |||
77 | barrier(); | 67 | barrier(); |
78 | } | 68 | } |
79 | 69 | ||
80 | static __inline__ int atomic_add_return(int i, atomic_t * v) | 70 | static inline int atomic_add_return(int i, atomic_t *v) |
81 | { | 71 | { |
82 | return __CS_LOOP(v, i, "ar"); | 72 | return __CS_LOOP(v, i, "ar"); |
83 | } | 73 | } |
@@ -87,7 +77,7 @@ static __inline__ int atomic_add_return(int i, atomic_t * v) | |||
87 | #define atomic_inc_return(_v) atomic_add_return(1, _v) | 77 | #define atomic_inc_return(_v) atomic_add_return(1, _v) |
88 | #define atomic_inc_and_test(_v) (atomic_add_return(1, _v) == 0) | 78 | #define atomic_inc_and_test(_v) (atomic_add_return(1, _v) == 0) |
89 | 79 | ||
90 | static __inline__ int atomic_sub_return(int i, atomic_t * v) | 80 | static inline int atomic_sub_return(int i, atomic_t *v) |
91 | { | 81 | { |
92 | return __CS_LOOP(v, i, "sr"); | 82 | return __CS_LOOP(v, i, "sr"); |
93 | } | 83 | } |
@@ -97,19 +87,19 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v) | |||
97 | #define atomic_dec_return(_v) atomic_sub_return(1, _v) | 87 | #define atomic_dec_return(_v) atomic_sub_return(1, _v) |
98 | #define atomic_dec_and_test(_v) (atomic_sub_return(1, _v) == 0) | 88 | #define atomic_dec_and_test(_v) (atomic_sub_return(1, _v) == 0) |
99 | 89 | ||
100 | static __inline__ void atomic_clear_mask(unsigned long mask, atomic_t * v) | 90 | static inline void atomic_clear_mask(unsigned long mask, atomic_t *v) |
101 | { | 91 | { |
102 | __CS_LOOP(v, ~mask, "nr"); | 92 | __CS_LOOP(v, ~mask, "nr"); |
103 | } | 93 | } |
104 | 94 | ||
105 | static __inline__ void atomic_set_mask(unsigned long mask, atomic_t * v) | 95 | static inline void atomic_set_mask(unsigned long mask, atomic_t *v) |
106 | { | 96 | { |
107 | __CS_LOOP(v, mask, "or"); | 97 | __CS_LOOP(v, mask, "or"); |
108 | } | 98 | } |
109 | 99 | ||
110 | #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) | 100 | #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) |
111 | 101 | ||
112 | static __inline__ int atomic_cmpxchg(atomic_t *v, int old, int new) | 102 | static inline int atomic_cmpxchg(atomic_t *v, int old, int new) |
113 | { | 103 | { |
114 | #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) | 104 | #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) |
115 | asm volatile( | 105 | asm volatile( |
@@ -127,7 +117,7 @@ static __inline__ int atomic_cmpxchg(atomic_t *v, int old, int new) | |||
127 | return old; | 117 | return old; |
128 | } | 118 | } |
129 | 119 | ||
130 | static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) | 120 | static inline int atomic_add_unless(atomic_t *v, int a, int u) |
131 | { | 121 | { |
132 | int c, old; | 122 | int c, old; |
133 | c = atomic_read(v); | 123 | c = atomic_read(v); |
@@ -146,9 +136,10 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) | |||
146 | 136 | ||
147 | #undef __CS_LOOP | 137 | #undef __CS_LOOP |
148 | 138 | ||
149 | #ifdef __s390x__ | ||
150 | #define ATOMIC64_INIT(i) { (i) } | 139 | #define ATOMIC64_INIT(i) { (i) } |
151 | 140 | ||
141 | #ifdef CONFIG_64BIT | ||
142 | |||
152 | #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) | 143 | #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) |
153 | 144 | ||
154 | #define __CSG_LOOP(ptr, op_val, op_string) ({ \ | 145 | #define __CSG_LOOP(ptr, op_val, op_string) ({ \ |
@@ -162,7 +153,7 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) | |||
162 | : "=&d" (old_val), "=&d" (new_val), \ | 153 | : "=&d" (old_val), "=&d" (new_val), \ |
163 | "=Q" (((atomic_t *)(ptr))->counter) \ | 154 | "=Q" (((atomic_t *)(ptr))->counter) \ |
164 | : "d" (op_val), "Q" (((atomic_t *)(ptr))->counter) \ | 155 | : "d" (op_val), "Q" (((atomic_t *)(ptr))->counter) \ |
165 | : "cc", "memory" ); \ | 156 | : "cc", "memory"); \ |
166 | new_val; \ | 157 | new_val; \ |
167 | }) | 158 | }) |
168 | 159 | ||
@@ -180,7 +171,7 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) | |||
180 | "=m" (((atomic_t *)(ptr))->counter) \ | 171 | "=m" (((atomic_t *)(ptr))->counter) \ |
181 | : "a" (ptr), "d" (op_val), \ | 172 | : "a" (ptr), "d" (op_val), \ |
182 | "m" (((atomic_t *)(ptr))->counter) \ | 173 | "m" (((atomic_t *)(ptr))->counter) \ |
183 | : "cc", "memory" ); \ | 174 | : "cc", "memory"); \ |
184 | new_val; \ | 175 | new_val; \ |
185 | }) | 176 | }) |
186 | 177 | ||
@@ -198,39 +189,29 @@ static inline void atomic64_set(atomic64_t *v, long long i) | |||
198 | barrier(); | 189 | barrier(); |
199 | } | 190 | } |
200 | 191 | ||
201 | static __inline__ long long atomic64_add_return(long long i, atomic64_t * v) | 192 | static inline long long atomic64_add_return(long long i, atomic64_t *v) |
202 | { | 193 | { |
203 | return __CSG_LOOP(v, i, "agr"); | 194 | return __CSG_LOOP(v, i, "agr"); |
204 | } | 195 | } |
205 | #define atomic64_add(_i, _v) atomic64_add_return(_i, _v) | ||
206 | #define atomic64_add_negative(_i, _v) (atomic64_add_return(_i, _v) < 0) | ||
207 | #define atomic64_inc(_v) atomic64_add_return(1, _v) | ||
208 | #define atomic64_inc_return(_v) atomic64_add_return(1, _v) | ||
209 | #define atomic64_inc_and_test(_v) (atomic64_add_return(1, _v) == 0) | ||
210 | 196 | ||
211 | static __inline__ long long atomic64_sub_return(long long i, atomic64_t * v) | 197 | static inline long long atomic64_sub_return(long long i, atomic64_t *v) |
212 | { | 198 | { |
213 | return __CSG_LOOP(v, i, "sgr"); | 199 | return __CSG_LOOP(v, i, "sgr"); |
214 | } | 200 | } |
215 | #define atomic64_sub(_i, _v) atomic64_sub_return(_i, _v) | ||
216 | #define atomic64_sub_and_test(_i, _v) (atomic64_sub_return(_i, _v) == 0) | ||
217 | #define atomic64_dec(_v) atomic64_sub_return(1, _v) | ||
218 | #define atomic64_dec_return(_v) atomic64_sub_return(1, _v) | ||
219 | #define atomic64_dec_and_test(_v) (atomic64_sub_return(1, _v) == 0) | ||
220 | 201 | ||
221 | static __inline__ void atomic64_clear_mask(unsigned long mask, atomic64_t * v) | 202 | static inline void atomic64_clear_mask(unsigned long mask, atomic64_t *v) |
222 | { | 203 | { |
223 | __CSG_LOOP(v, ~mask, "ngr"); | 204 | __CSG_LOOP(v, ~mask, "ngr"); |
224 | } | 205 | } |
225 | 206 | ||
226 | static __inline__ void atomic64_set_mask(unsigned long mask, atomic64_t * v) | 207 | static inline void atomic64_set_mask(unsigned long mask, atomic64_t *v) |
227 | { | 208 | { |
228 | __CSG_LOOP(v, mask, "ogr"); | 209 | __CSG_LOOP(v, mask, "ogr"); |
229 | } | 210 | } |
230 | 211 | ||
231 | #define atomic64_xchg(v, new) (xchg(&((v)->counter), new)) | 212 | #define atomic64_xchg(v, new) (xchg(&((v)->counter), new)) |
232 | 213 | ||
233 | static __inline__ long long atomic64_cmpxchg(atomic64_t *v, | 214 | static inline long long atomic64_cmpxchg(atomic64_t *v, |
234 | long long old, long long new) | 215 | long long old, long long new) |
235 | { | 216 | { |
236 | #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) | 217 | #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) |
@@ -249,8 +230,112 @@ static __inline__ long long atomic64_cmpxchg(atomic64_t *v, | |||
249 | return old; | 230 | return old; |
250 | } | 231 | } |
251 | 232 | ||
252 | static __inline__ int atomic64_add_unless(atomic64_t *v, | 233 | #undef __CSG_LOOP |
253 | long long a, long long u) | 234 | |
235 | #else /* CONFIG_64BIT */ | ||
236 | |||
237 | typedef struct { | ||
238 | long long counter; | ||
239 | } atomic64_t; | ||
240 | |||
241 | static inline long long atomic64_read(const atomic64_t *v) | ||
242 | { | ||
243 | register_pair rp; | ||
244 | |||
245 | asm volatile( | ||
246 | " lm %0,%N0,0(%1)" | ||
247 | : "=&d" (rp) | ||
248 | : "a" (&v->counter), "m" (v->counter) | ||
249 | ); | ||
250 | return rp.pair; | ||
251 | } | ||
252 | |||
253 | static inline void atomic64_set(atomic64_t *v, long long i) | ||
254 | { | ||
255 | register_pair rp = {.pair = i}; | ||
256 | |||
257 | asm volatile( | ||
258 | " stm %1,%N1,0(%2)" | ||
259 | : "=m" (v->counter) | ||
260 | : "d" (rp), "a" (&v->counter) | ||
261 | ); | ||
262 | } | ||
263 | |||
264 | static inline long long atomic64_xchg(atomic64_t *v, long long new) | ||
265 | { | ||
266 | register_pair rp_new = {.pair = new}; | ||
267 | register_pair rp_old; | ||
268 | |||
269 | asm volatile( | ||
270 | " lm %0,%N0,0(%2)\n" | ||
271 | "0: cds %0,%3,0(%2)\n" | ||
272 | " jl 0b\n" | ||
273 | : "=&d" (rp_old), "+m" (v->counter) | ||
274 | : "a" (&v->counter), "d" (rp_new) | ||
275 | : "cc"); | ||
276 | return rp_old.pair; | ||
277 | } | ||
278 | |||
279 | static inline long long atomic64_cmpxchg(atomic64_t *v, | ||
280 | long long old, long long new) | ||
281 | { | ||
282 | register_pair rp_old = {.pair = old}; | ||
283 | register_pair rp_new = {.pair = new}; | ||
284 | |||
285 | asm volatile( | ||
286 | " cds %0,%3,0(%2)" | ||
287 | : "+&d" (rp_old), "+m" (v->counter) | ||
288 | : "a" (&v->counter), "d" (rp_new) | ||
289 | : "cc"); | ||
290 | return rp_old.pair; | ||
291 | } | ||
292 | |||
293 | |||
294 | static inline long long atomic64_add_return(long long i, atomic64_t *v) | ||
295 | { | ||
296 | long long old, new; | ||
297 | |||
298 | do { | ||
299 | old = atomic64_read(v); | ||
300 | new = old + i; | ||
301 | } while (atomic64_cmpxchg(v, old, new) != old); | ||
302 | return new; | ||
303 | } | ||
304 | |||
305 | static inline long long atomic64_sub_return(long long i, atomic64_t *v) | ||
306 | { | ||
307 | long long old, new; | ||
308 | |||
309 | do { | ||
310 | old = atomic64_read(v); | ||
311 | new = old - i; | ||
312 | } while (atomic64_cmpxchg(v, old, new) != old); | ||
313 | return new; | ||
314 | } | ||
315 | |||
316 | static inline void atomic64_set_mask(unsigned long long mask, atomic64_t *v) | ||
317 | { | ||
318 | long long old, new; | ||
319 | |||
320 | do { | ||
321 | old = atomic64_read(v); | ||
322 | new = old | mask; | ||
323 | } while (atomic64_cmpxchg(v, old, new) != old); | ||
324 | } | ||
325 | |||
326 | static inline void atomic64_clear_mask(unsigned long long mask, atomic64_t *v) | ||
327 | { | ||
328 | long long old, new; | ||
329 | |||
330 | do { | ||
331 | old = atomic64_read(v); | ||
332 | new = old & mask; | ||
333 | } while (atomic64_cmpxchg(v, old, new) != old); | ||
334 | } | ||
335 | |||
336 | #endif /* CONFIG_64BIT */ | ||
337 | |||
338 | static inline int atomic64_add_unless(atomic64_t *v, long long a, long long u) | ||
254 | { | 339 | { |
255 | long long c, old; | 340 | long long c, old; |
256 | c = atomic64_read(v); | 341 | c = atomic64_read(v); |
@@ -265,15 +350,17 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, | |||
265 | return c != u; | 350 | return c != u; |
266 | } | 351 | } |
267 | 352 | ||
268 | #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) | 353 | #define atomic64_add(_i, _v) atomic64_add_return(_i, _v) |
269 | 354 | #define atomic64_add_negative(_i, _v) (atomic64_add_return(_i, _v) < 0) | |
270 | #undef __CSG_LOOP | 355 | #define atomic64_inc(_v) atomic64_add_return(1, _v) |
271 | 356 | #define atomic64_inc_return(_v) atomic64_add_return(1, _v) | |
272 | #else /* __s390x__ */ | 357 | #define atomic64_inc_and_test(_v) (atomic64_add_return(1, _v) == 0) |
273 | 358 | #define atomic64_sub(_i, _v) atomic64_sub_return(_i, _v) | |
274 | #include <asm-generic/atomic64.h> | 359 | #define atomic64_sub_and_test(_i, _v) (atomic64_sub_return(_i, _v) == 0) |
275 | 360 | #define atomic64_dec(_v) atomic64_sub_return(1, _v) | |
276 | #endif /* __s390x__ */ | 361 | #define atomic64_dec_return(_v) atomic64_sub_return(1, _v) |
362 | #define atomic64_dec_and_test(_v) (atomic64_sub_return(1, _v) == 0) | ||
363 | #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) | ||
277 | 364 | ||
278 | #define smp_mb__before_atomic_dec() smp_mb() | 365 | #define smp_mb__before_atomic_dec() smp_mb() |
279 | #define smp_mb__after_atomic_dec() smp_mb() | 366 | #define smp_mb__after_atomic_dec() smp_mb() |
@@ -281,5 +368,5 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, | |||
281 | #define smp_mb__after_atomic_inc() smp_mb() | 368 | #define smp_mb__after_atomic_inc() smp_mb() |
282 | 369 | ||
283 | #include <asm-generic/atomic-long.h> | 370 | #include <asm-generic/atomic-long.h> |
284 | #endif /* __KERNEL__ */ | 371 | |
285 | #endif /* __ARCH_S390_ATOMIC__ */ | 372 | #endif /* __ARCH_S390_ATOMIC__ */ |
diff --git a/arch/s390/include/asm/checksum.h b/arch/s390/include/asm/checksum.h index d5a8e7c1477c..6c00f6800a34 100644 --- a/arch/s390/include/asm/checksum.h +++ b/arch/s390/include/asm/checksum.h | |||
@@ -78,28 +78,11 @@ csum_partial_copy_nocheck (const void *src, void *dst, int len, __wsum sum) | |||
78 | */ | 78 | */ |
79 | static inline __sum16 csum_fold(__wsum sum) | 79 | static inline __sum16 csum_fold(__wsum sum) |
80 | { | 80 | { |
81 | #ifndef __s390x__ | 81 | u32 csum = (__force u32) sum; |
82 | register_pair rp; | ||
83 | 82 | ||
84 | asm volatile( | 83 | csum += (csum >> 16) + (csum << 16); |
85 | " slr %N1,%N1\n" /* %0 = H L */ | 84 | csum >>= 16; |
86 | " lr %1,%0\n" /* %0 = H L, %1 = H L 0 0 */ | 85 | return (__force __sum16) ~csum; |
87 | " srdl %1,16\n" /* %0 = H L, %1 = 0 H L 0 */ | ||
88 | " alr %1,%N1\n" /* %0 = H L, %1 = L H L 0 */ | ||
89 | " alr %0,%1\n" /* %0 = H+L+C L+H */ | ||
90 | " srl %0,16\n" /* %0 = H+L+C */ | ||
91 | : "+&d" (sum), "=d" (rp) : : "cc"); | ||
92 | #else /* __s390x__ */ | ||
93 | asm volatile( | ||
94 | " sr 3,3\n" /* %0 = H*65536 + L */ | ||
95 | " lr 2,%0\n" /* %0 = H L, 2/3 = H L / 0 0 */ | ||
96 | " srdl 2,16\n" /* %0 = H L, 2/3 = 0 H / L 0 */ | ||
97 | " alr 2,3\n" /* %0 = H L, 2/3 = L H / L 0 */ | ||
98 | " alr %0,2\n" /* %0 = H+L+C L+H */ | ||
99 | " srl %0,16\n" /* %0 = H+L+C */ | ||
100 | : "+&d" (sum) : : "cc", "2", "3"); | ||
101 | #endif /* __s390x__ */ | ||
102 | return (__force __sum16) ~sum; | ||
103 | } | 86 | } |
104 | 87 | ||
105 | /* | 88 | /* |
diff --git a/arch/s390/include/asm/chsc.h b/arch/s390/include/asm/chsc.h index 807997f7414b..4943654ed7fd 100644 --- a/arch/s390/include/asm/chsc.h +++ b/arch/s390/include/asm/chsc.h | |||
@@ -125,4 +125,32 @@ struct chsc_cpd_info { | |||
125 | #define CHSC_INFO_CPD _IOWR(CHSC_IOCTL_MAGIC, 0x87, struct chsc_cpd_info) | 125 | #define CHSC_INFO_CPD _IOWR(CHSC_IOCTL_MAGIC, 0x87, struct chsc_cpd_info) |
126 | #define CHSC_INFO_DCAL _IOWR(CHSC_IOCTL_MAGIC, 0x88, struct chsc_dcal) | 126 | #define CHSC_INFO_DCAL _IOWR(CHSC_IOCTL_MAGIC, 0x88, struct chsc_dcal) |
127 | 127 | ||
128 | #ifdef __KERNEL__ | ||
129 | |||
130 | struct css_general_char { | ||
131 | u64 : 12; | ||
132 | u32 dynio : 1; /* bit 12 */ | ||
133 | u32 : 28; | ||
134 | u32 aif : 1; /* bit 41 */ | ||
135 | u32 : 3; | ||
136 | u32 mcss : 1; /* bit 45 */ | ||
137 | u32 fcs : 1; /* bit 46 */ | ||
138 | u32 : 1; | ||
139 | u32 ext_mb : 1; /* bit 48 */ | ||
140 | u32 : 7; | ||
141 | u32 aif_tdd : 1; /* bit 56 */ | ||
142 | u32 : 1; | ||
143 | u32 qebsm : 1; /* bit 58 */ | ||
144 | u32 : 8; | ||
145 | u32 aif_osa : 1; /* bit 67 */ | ||
146 | u32 : 14; | ||
147 | u32 cib : 1; /* bit 82 */ | ||
148 | u32 : 5; | ||
149 | u32 fcx : 1; /* bit 88 */ | ||
150 | u32 : 7; | ||
151 | }__attribute__((packed)); | ||
152 | |||
153 | extern struct css_general_char css_general_characteristics; | ||
154 | |||
155 | #endif /* __KERNEL__ */ | ||
128 | #endif | 156 | #endif |
diff --git a/arch/s390/include/asm/cio.h b/arch/s390/include/asm/cio.h index 619bf94b11f1..e85679af54dd 100644 --- a/arch/s390/include/asm/cio.h +++ b/arch/s390/include/asm/cio.h | |||
@@ -15,228 +15,7 @@ | |||
15 | #define LPM_ANYPATH 0xff | 15 | #define LPM_ANYPATH 0xff |
16 | #define __MAX_CSSID 0 | 16 | #define __MAX_CSSID 0 |
17 | 17 | ||
18 | /** | 18 | #include <asm/scsw.h> |
19 | * struct cmd_scsw - command-mode subchannel status word | ||
20 | * @key: subchannel key | ||
21 | * @sctl: suspend control | ||
22 | * @eswf: esw format | ||
23 | * @cc: deferred condition code | ||
24 | * @fmt: format | ||
25 | * @pfch: prefetch | ||
26 | * @isic: initial-status interruption control | ||
27 | * @alcc: address-limit checking control | ||
28 | * @ssi: suppress-suspended interruption | ||
29 | * @zcc: zero condition code | ||
30 | * @ectl: extended control | ||
31 | * @pno: path not operational | ||
32 | * @res: reserved | ||
33 | * @fctl: function control | ||
34 | * @actl: activity control | ||
35 | * @stctl: status control | ||
36 | * @cpa: channel program address | ||
37 | * @dstat: device status | ||
38 | * @cstat: subchannel status | ||
39 | * @count: residual count | ||
40 | */ | ||
41 | struct cmd_scsw { | ||
42 | __u32 key : 4; | ||
43 | __u32 sctl : 1; | ||
44 | __u32 eswf : 1; | ||
45 | __u32 cc : 2; | ||
46 | __u32 fmt : 1; | ||
47 | __u32 pfch : 1; | ||
48 | __u32 isic : 1; | ||
49 | __u32 alcc : 1; | ||
50 | __u32 ssi : 1; | ||
51 | __u32 zcc : 1; | ||
52 | __u32 ectl : 1; | ||
53 | __u32 pno : 1; | ||
54 | __u32 res : 1; | ||
55 | __u32 fctl : 3; | ||
56 | __u32 actl : 7; | ||
57 | __u32 stctl : 5; | ||
58 | __u32 cpa; | ||
59 | __u32 dstat : 8; | ||
60 | __u32 cstat : 8; | ||
61 | __u32 count : 16; | ||
62 | } __attribute__ ((packed)); | ||
63 | |||
64 | /** | ||
65 | * struct tm_scsw - transport-mode subchannel status word | ||
66 | * @key: subchannel key | ||
67 | * @eswf: esw format | ||
68 | * @cc: deferred condition code | ||
69 | * @fmt: format | ||
70 | * @x: IRB-format control | ||
71 | * @q: interrogate-complete | ||
72 | * @ectl: extended control | ||
73 | * @pno: path not operational | ||
74 | * @fctl: function control | ||
75 | * @actl: activity control | ||
76 | * @stctl: status control | ||
77 | * @tcw: TCW address | ||
78 | * @dstat: device status | ||
79 | * @cstat: subchannel status | ||
80 | * @fcxs: FCX status | ||
81 | * @schxs: subchannel-extended status | ||
82 | */ | ||
83 | struct tm_scsw { | ||
84 | u32 key:4; | ||
85 | u32 :1; | ||
86 | u32 eswf:1; | ||
87 | u32 cc:2; | ||
88 | u32 fmt:3; | ||
89 | u32 x:1; | ||
90 | u32 q:1; | ||
91 | u32 :1; | ||
92 | u32 ectl:1; | ||
93 | u32 pno:1; | ||
94 | u32 :1; | ||
95 | u32 fctl:3; | ||
96 | u32 actl:7; | ||
97 | u32 stctl:5; | ||
98 | u32 tcw; | ||
99 | u32 dstat:8; | ||
100 | u32 cstat:8; | ||
101 | u32 fcxs:8; | ||
102 | u32 schxs:8; | ||
103 | } __attribute__ ((packed)); | ||
104 | |||
105 | /** | ||
106 | * union scsw - subchannel status word | ||
107 | * @cmd: command-mode SCSW | ||
108 | * @tm: transport-mode SCSW | ||
109 | */ | ||
110 | union scsw { | ||
111 | struct cmd_scsw cmd; | ||
112 | struct tm_scsw tm; | ||
113 | } __attribute__ ((packed)); | ||
114 | |||
115 | int scsw_is_tm(union scsw *scsw); | ||
116 | u32 scsw_key(union scsw *scsw); | ||
117 | u32 scsw_eswf(union scsw *scsw); | ||
118 | u32 scsw_cc(union scsw *scsw); | ||
119 | u32 scsw_ectl(union scsw *scsw); | ||
120 | u32 scsw_pno(union scsw *scsw); | ||
121 | u32 scsw_fctl(union scsw *scsw); | ||
122 | u32 scsw_actl(union scsw *scsw); | ||
123 | u32 scsw_stctl(union scsw *scsw); | ||
124 | u32 scsw_dstat(union scsw *scsw); | ||
125 | u32 scsw_cstat(union scsw *scsw); | ||
126 | int scsw_is_solicited(union scsw *scsw); | ||
127 | int scsw_is_valid_key(union scsw *scsw); | ||
128 | int scsw_is_valid_eswf(union scsw *scsw); | ||
129 | int scsw_is_valid_cc(union scsw *scsw); | ||
130 | int scsw_is_valid_ectl(union scsw *scsw); | ||
131 | int scsw_is_valid_pno(union scsw *scsw); | ||
132 | int scsw_is_valid_fctl(union scsw *scsw); | ||
133 | int scsw_is_valid_actl(union scsw *scsw); | ||
134 | int scsw_is_valid_stctl(union scsw *scsw); | ||
135 | int scsw_is_valid_dstat(union scsw *scsw); | ||
136 | int scsw_is_valid_cstat(union scsw *scsw); | ||
137 | int scsw_cmd_is_valid_key(union scsw *scsw); | ||
138 | int scsw_cmd_is_valid_sctl(union scsw *scsw); | ||
139 | int scsw_cmd_is_valid_eswf(union scsw *scsw); | ||
140 | int scsw_cmd_is_valid_cc(union scsw *scsw); | ||
141 | int scsw_cmd_is_valid_fmt(union scsw *scsw); | ||
142 | int scsw_cmd_is_valid_pfch(union scsw *scsw); | ||
143 | int scsw_cmd_is_valid_isic(union scsw *scsw); | ||
144 | int scsw_cmd_is_valid_alcc(union scsw *scsw); | ||
145 | int scsw_cmd_is_valid_ssi(union scsw *scsw); | ||
146 | int scsw_cmd_is_valid_zcc(union scsw *scsw); | ||
147 | int scsw_cmd_is_valid_ectl(union scsw *scsw); | ||
148 | int scsw_cmd_is_valid_pno(union scsw *scsw); | ||
149 | int scsw_cmd_is_valid_fctl(union scsw *scsw); | ||
150 | int scsw_cmd_is_valid_actl(union scsw *scsw); | ||
151 | int scsw_cmd_is_valid_stctl(union scsw *scsw); | ||
152 | int scsw_cmd_is_valid_dstat(union scsw *scsw); | ||
153 | int scsw_cmd_is_valid_cstat(union scsw *scsw); | ||
154 | int scsw_cmd_is_solicited(union scsw *scsw); | ||
155 | int scsw_tm_is_valid_key(union scsw *scsw); | ||
156 | int scsw_tm_is_valid_eswf(union scsw *scsw); | ||
157 | int scsw_tm_is_valid_cc(union scsw *scsw); | ||
158 | int scsw_tm_is_valid_fmt(union scsw *scsw); | ||
159 | int scsw_tm_is_valid_x(union scsw *scsw); | ||
160 | int scsw_tm_is_valid_q(union scsw *scsw); | ||
161 | int scsw_tm_is_valid_ectl(union scsw *scsw); | ||
162 | int scsw_tm_is_valid_pno(union scsw *scsw); | ||
163 | int scsw_tm_is_valid_fctl(union scsw *scsw); | ||
164 | int scsw_tm_is_valid_actl(union scsw *scsw); | ||
165 | int scsw_tm_is_valid_stctl(union scsw *scsw); | ||
166 | int scsw_tm_is_valid_dstat(union scsw *scsw); | ||
167 | int scsw_tm_is_valid_cstat(union scsw *scsw); | ||
168 | int scsw_tm_is_valid_fcxs(union scsw *scsw); | ||
169 | int scsw_tm_is_valid_schxs(union scsw *scsw); | ||
170 | int scsw_tm_is_solicited(union scsw *scsw); | ||
171 | |||
172 | #define SCSW_FCTL_CLEAR_FUNC 0x1 | ||
173 | #define SCSW_FCTL_HALT_FUNC 0x2 | ||
174 | #define SCSW_FCTL_START_FUNC 0x4 | ||
175 | |||
176 | #define SCSW_ACTL_SUSPENDED 0x1 | ||
177 | #define SCSW_ACTL_DEVACT 0x2 | ||
178 | #define SCSW_ACTL_SCHACT 0x4 | ||
179 | #define SCSW_ACTL_CLEAR_PEND 0x8 | ||
180 | #define SCSW_ACTL_HALT_PEND 0x10 | ||
181 | #define SCSW_ACTL_START_PEND 0x20 | ||
182 | #define SCSW_ACTL_RESUME_PEND 0x40 | ||
183 | |||
184 | #define SCSW_STCTL_STATUS_PEND 0x1 | ||
185 | #define SCSW_STCTL_SEC_STATUS 0x2 | ||
186 | #define SCSW_STCTL_PRIM_STATUS 0x4 | ||
187 | #define SCSW_STCTL_INTER_STATUS 0x8 | ||
188 | #define SCSW_STCTL_ALERT_STATUS 0x10 | ||
189 | |||
190 | #define DEV_STAT_ATTENTION 0x80 | ||
191 | #define DEV_STAT_STAT_MOD 0x40 | ||
192 | #define DEV_STAT_CU_END 0x20 | ||
193 | #define DEV_STAT_BUSY 0x10 | ||
194 | #define DEV_STAT_CHN_END 0x08 | ||
195 | #define DEV_STAT_DEV_END 0x04 | ||
196 | #define DEV_STAT_UNIT_CHECK 0x02 | ||
197 | #define DEV_STAT_UNIT_EXCEP 0x01 | ||
198 | |||
199 | #define SCHN_STAT_PCI 0x80 | ||
200 | #define SCHN_STAT_INCORR_LEN 0x40 | ||
201 | #define SCHN_STAT_PROG_CHECK 0x20 | ||
202 | #define SCHN_STAT_PROT_CHECK 0x10 | ||
203 | #define SCHN_STAT_CHN_DATA_CHK 0x08 | ||
204 | #define SCHN_STAT_CHN_CTRL_CHK 0x04 | ||
205 | #define SCHN_STAT_INTF_CTRL_CHK 0x02 | ||
206 | #define SCHN_STAT_CHAIN_CHECK 0x01 | ||
207 | |||
208 | /* | ||
209 | * architectured values for first sense byte | ||
210 | */ | ||
211 | #define SNS0_CMD_REJECT 0x80 | ||
212 | #define SNS_CMD_REJECT SNS0_CMD_REJEC | ||
213 | #define SNS0_INTERVENTION_REQ 0x40 | ||
214 | #define SNS0_BUS_OUT_CHECK 0x20 | ||
215 | #define SNS0_EQUIPMENT_CHECK 0x10 | ||
216 | #define SNS0_DATA_CHECK 0x08 | ||
217 | #define SNS0_OVERRUN 0x04 | ||
218 | #define SNS0_INCOMPL_DOMAIN 0x01 | ||
219 | |||
220 | /* | ||
221 | * architectured values for second sense byte | ||
222 | */ | ||
223 | #define SNS1_PERM_ERR 0x80 | ||
224 | #define SNS1_INV_TRACK_FORMAT 0x40 | ||
225 | #define SNS1_EOC 0x20 | ||
226 | #define SNS1_MESSAGE_TO_OPER 0x10 | ||
227 | #define SNS1_NO_REC_FOUND 0x08 | ||
228 | #define SNS1_FILE_PROTECTED 0x04 | ||
229 | #define SNS1_WRITE_INHIBITED 0x02 | ||
230 | #define SNS1_INPRECISE_END 0x01 | ||
231 | |||
232 | /* | ||
233 | * architectured values for third sense byte | ||
234 | */ | ||
235 | #define SNS2_REQ_INH_WRITE 0x80 | ||
236 | #define SNS2_CORRECTABLE 0x40 | ||
237 | #define SNS2_FIRST_LOG_ERR 0x20 | ||
238 | #define SNS2_ENV_DATA_PRESENT 0x10 | ||
239 | #define SNS2_INPRECISE_END 0x04 | ||
240 | 19 | ||
241 | /** | 20 | /** |
242 | * struct ccw1 - channel command word | 21 | * struct ccw1 - channel command word |
diff --git a/arch/s390/include/asm/cpu.h b/arch/s390/include/asm/cpu.h new file mode 100644 index 000000000000..471234b90574 --- /dev/null +++ b/arch/s390/include/asm/cpu.h | |||
@@ -0,0 +1,26 @@ | |||
1 | /* | ||
2 | * Copyright IBM Corp. 2000,2009 | ||
3 | * Author(s): Hartmut Penner <hp@de.ibm.com>, | ||
4 | * Martin Schwidefsky <schwidefsky@de.ibm.com>, | ||
5 | * Christian Ehrhardt <ehrhardt@de.ibm.com>, | ||
6 | */ | ||
7 | |||
8 | #ifndef _ASM_S390_CPU_H | ||
9 | #define _ASM_S390_CPU_H | ||
10 | |||
11 | #define MAX_CPU_ADDRESS 255 | ||
12 | |||
13 | #ifndef __ASSEMBLY__ | ||
14 | |||
15 | #include <linux/types.h> | ||
16 | |||
17 | struct cpuid | ||
18 | { | ||
19 | unsigned int version : 8; | ||
20 | unsigned int ident : 24; | ||
21 | unsigned int machine : 16; | ||
22 | unsigned int unused : 16; | ||
23 | } __packed; | ||
24 | |||
25 | #endif /* __ASSEMBLY__ */ | ||
26 | #endif /* _ASM_S390_CPU_H */ | ||
diff --git a/arch/s390/include/asm/cpuid.h b/arch/s390/include/asm/cpuid.h deleted file mode 100644 index 07836a2e5222..000000000000 --- a/arch/s390/include/asm/cpuid.h +++ /dev/null | |||
@@ -1,25 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright IBM Corp. 2000,2009 | ||
3 | * Author(s): Hartmut Penner <hp@de.ibm.com>, | ||
4 | * Martin Schwidefsky <schwidefsky@de.ibm.com> | ||
5 | * Christian Ehrhardt <ehrhardt@de.ibm.com> | ||
6 | */ | ||
7 | |||
8 | #ifndef _ASM_S390_CPUID_H_ | ||
9 | #define _ASM_S390_CPUID_H_ | ||
10 | |||
11 | /* | ||
12 | * CPU type and hardware bug flags. Kept separately for each CPU. | ||
13 | * Members of this structure are referenced in head.S, so think twice | ||
14 | * before touching them. [mj] | ||
15 | */ | ||
16 | |||
17 | typedef struct | ||
18 | { | ||
19 | unsigned int version : 8; | ||
20 | unsigned int ident : 24; | ||
21 | unsigned int machine : 16; | ||
22 | unsigned int unused : 16; | ||
23 | } __attribute__ ((packed)) cpuid_t; | ||
24 | |||
25 | #endif /* _ASM_S390_CPUID_H_ */ | ||
diff --git a/arch/s390/include/asm/debug.h b/arch/s390/include/asm/debug.h index 31ed5686a968..18124b75a7ab 100644 --- a/arch/s390/include/asm/debug.h +++ b/arch/s390/include/asm/debug.h | |||
@@ -167,6 +167,10 @@ debug_text_event(debug_info_t* id, int level, const char* txt) | |||
167 | return debug_event_common(id,level,txt,strlen(txt)); | 167 | return debug_event_common(id,level,txt,strlen(txt)); |
168 | } | 168 | } |
169 | 169 | ||
170 | /* | ||
171 | * IMPORTANT: Use "%s" in sprintf format strings with care! Only pointers are | ||
172 | * stored in the s390dbf. See Documentation/s390/s390dbf.txt for more details! | ||
173 | */ | ||
170 | extern debug_entry_t * | 174 | extern debug_entry_t * |
171 | debug_sprintf_event(debug_info_t* id,int level,char *string,...) | 175 | debug_sprintf_event(debug_info_t* id,int level,char *string,...) |
172 | __attribute__ ((format(printf, 3, 4))); | 176 | __attribute__ ((format(printf, 3, 4))); |
@@ -206,7 +210,10 @@ debug_text_exception(debug_info_t* id, int level, const char* txt) | |||
206 | return debug_exception_common(id,level,txt,strlen(txt)); | 210 | return debug_exception_common(id,level,txt,strlen(txt)); |
207 | } | 211 | } |
208 | 212 | ||
209 | 213 | /* | |
214 | * IMPORTANT: Use "%s" in sprintf format strings with care! Only pointers are | ||
215 | * stored in the s390dbf. See Documentation/s390/s390dbf.txt for more details! | ||
216 | */ | ||
210 | extern debug_entry_t * | 217 | extern debug_entry_t * |
211 | debug_sprintf_exception(debug_info_t* id,int level,char *string,...) | 218 | debug_sprintf_exception(debug_info_t* id,int level,char *string,...) |
212 | __attribute__ ((format(printf, 3, 4))); | 219 | __attribute__ ((format(printf, 3, 4))); |
diff --git a/arch/s390/include/asm/hardirq.h b/arch/s390/include/asm/hardirq.h index 89ec7056da28..498bc3892385 100644 --- a/arch/s390/include/asm/hardirq.h +++ b/arch/s390/include/asm/hardirq.h | |||
@@ -18,13 +18,6 @@ | |||
18 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
19 | #include <asm/lowcore.h> | 19 | #include <asm/lowcore.h> |
20 | 20 | ||
21 | /* irq_cpustat_t is unused currently, but could be converted | ||
22 | * into a percpu variable instead of storing softirq_pending | ||
23 | * on the lowcore */ | ||
24 | typedef struct { | ||
25 | unsigned int __softirq_pending; | ||
26 | } irq_cpustat_t; | ||
27 | |||
28 | #define local_softirq_pending() (S390_lowcore.softirq_pending) | 21 | #define local_softirq_pending() (S390_lowcore.softirq_pending) |
29 | 22 | ||
30 | #define __ARCH_IRQ_STAT | 23 | #define __ARCH_IRQ_STAT |
diff --git a/arch/s390/include/asm/ipl.h b/arch/s390/include/asm/ipl.h index 1171e6d144a3..5e95d95450b3 100644 --- a/arch/s390/include/asm/ipl.h +++ b/arch/s390/include/asm/ipl.h | |||
@@ -57,6 +57,8 @@ struct ipl_block_fcp { | |||
57 | } __attribute__((packed)); | 57 | } __attribute__((packed)); |
58 | 58 | ||
59 | #define DIAG308_VMPARM_SIZE 64 | 59 | #define DIAG308_VMPARM_SIZE 64 |
60 | #define DIAG308_SCPDATA_SIZE (PAGE_SIZE - (sizeof(struct ipl_list_hdr) + \ | ||
61 | offsetof(struct ipl_block_fcp, scp_data))) | ||
60 | 62 | ||
61 | struct ipl_block_ccw { | 63 | struct ipl_block_ccw { |
62 | u8 load_parm[8]; | 64 | u8 load_parm[8]; |
@@ -91,7 +93,8 @@ extern void do_halt(void); | |||
91 | extern void do_poff(void); | 93 | extern void do_poff(void); |
92 | extern void ipl_save_parameters(void); | 94 | extern void ipl_save_parameters(void); |
93 | extern void ipl_update_parameters(void); | 95 | extern void ipl_update_parameters(void); |
94 | extern void get_ipl_vmparm(char *); | 96 | extern size_t append_ipl_vmparm(char *, size_t); |
97 | extern size_t append_ipl_scpdata(char *, size_t); | ||
95 | 98 | ||
96 | enum { | 99 | enum { |
97 | IPL_DEVNO_VALID = 1, | 100 | IPL_DEVNO_VALID = 1, |
diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h index 1cd02f6073a0..698988f69403 100644 --- a/arch/s390/include/asm/kvm_host.h +++ b/arch/s390/include/asm/kvm_host.h | |||
@@ -17,7 +17,7 @@ | |||
17 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
18 | #include <linux/kvm_host.h> | 18 | #include <linux/kvm_host.h> |
19 | #include <asm/debug.h> | 19 | #include <asm/debug.h> |
20 | #include <asm/cpuid.h> | 20 | #include <asm/cpu.h> |
21 | 21 | ||
22 | #define KVM_MAX_VCPUS 64 | 22 | #define KVM_MAX_VCPUS 64 |
23 | #define KVM_MEMORY_SLOTS 32 | 23 | #define KVM_MEMORY_SLOTS 32 |
@@ -217,8 +217,8 @@ struct kvm_vcpu_arch { | |||
217 | struct hrtimer ckc_timer; | 217 | struct hrtimer ckc_timer; |
218 | struct tasklet_struct tasklet; | 218 | struct tasklet_struct tasklet; |
219 | union { | 219 | union { |
220 | cpuid_t cpu_id; | 220 | struct cpuid cpu_id; |
221 | u64 stidp_data; | 221 | u64 stidp_data; |
222 | }; | 222 | }; |
223 | }; | 223 | }; |
224 | 224 | ||
diff --git a/arch/s390/include/asm/kvm_virtio.h b/arch/s390/include/asm/kvm_virtio.h index 0503936f101f..acdfdff26611 100644 --- a/arch/s390/include/asm/kvm_virtio.h +++ b/arch/s390/include/asm/kvm_virtio.h | |||
@@ -54,14 +54,4 @@ struct kvm_vqconfig { | |||
54 | * This is pagesize for historical reasons. */ | 54 | * This is pagesize for historical reasons. */ |
55 | #define KVM_S390_VIRTIO_RING_ALIGN 4096 | 55 | #define KVM_S390_VIRTIO_RING_ALIGN 4096 |
56 | 56 | ||
57 | #ifdef __KERNEL__ | ||
58 | /* early virtio console setup */ | ||
59 | #ifdef CONFIG_S390_GUEST | ||
60 | extern void s390_virtio_console_init(void); | ||
61 | #else | ||
62 | static inline void s390_virtio_console_init(void) | ||
63 | { | ||
64 | } | ||
65 | #endif /* CONFIG_VIRTIO_CONSOLE */ | ||
66 | #endif /* __KERNEL__ */ | ||
67 | #endif | 57 | #endif |
diff --git a/arch/s390/include/asm/lowcore.h b/arch/s390/include/asm/lowcore.h index 5046ad6b7a63..6bc9426a6fbf 100644 --- a/arch/s390/include/asm/lowcore.h +++ b/arch/s390/include/asm/lowcore.h | |||
@@ -132,7 +132,7 @@ | |||
132 | 132 | ||
133 | #ifndef __ASSEMBLY__ | 133 | #ifndef __ASSEMBLY__ |
134 | 134 | ||
135 | #include <asm/cpuid.h> | 135 | #include <asm/cpu.h> |
136 | #include <asm/ptrace.h> | 136 | #include <asm/ptrace.h> |
137 | #include <linux/types.h> | 137 | #include <linux/types.h> |
138 | 138 | ||
@@ -275,7 +275,7 @@ struct _lowcore | |||
275 | __u32 user_exec_asce; /* 0x02ac */ | 275 | __u32 user_exec_asce; /* 0x02ac */ |
276 | 276 | ||
277 | /* SMP info area */ | 277 | /* SMP info area */ |
278 | cpuid_t cpu_id; /* 0x02b0 */ | 278 | struct cpuid cpu_id; /* 0x02b0 */ |
279 | __u32 cpu_nr; /* 0x02b8 */ | 279 | __u32 cpu_nr; /* 0x02b8 */ |
280 | __u32 softirq_pending; /* 0x02bc */ | 280 | __u32 softirq_pending; /* 0x02bc */ |
281 | __u32 percpu_offset; /* 0x02c0 */ | 281 | __u32 percpu_offset; /* 0x02c0 */ |
@@ -380,7 +380,7 @@ struct _lowcore | |||
380 | __u64 user_exec_asce; /* 0x0318 */ | 380 | __u64 user_exec_asce; /* 0x0318 */ |
381 | 381 | ||
382 | /* SMP info area */ | 382 | /* SMP info area */ |
383 | cpuid_t cpu_id; /* 0x0320 */ | 383 | struct cpuid cpu_id; /* 0x0320 */ |
384 | __u32 cpu_nr; /* 0x0328 */ | 384 | __u32 cpu_nr; /* 0x0328 */ |
385 | __u32 softirq_pending; /* 0x032c */ | 385 | __u32 softirq_pending; /* 0x032c */ |
386 | __u64 percpu_offset; /* 0x0330 */ | 386 | __u64 percpu_offset; /* 0x0330 */ |
diff --git a/arch/s390/include/asm/mmu.h b/arch/s390/include/asm/mmu.h index 3b59216e6284..03be99919d62 100644 --- a/arch/s390/include/asm/mmu.h +++ b/arch/s390/include/asm/mmu.h | |||
@@ -2,6 +2,7 @@ | |||
2 | #define __MMU_H | 2 | #define __MMU_H |
3 | 3 | ||
4 | typedef struct { | 4 | typedef struct { |
5 | spinlock_t list_lock; | ||
5 | struct list_head crst_list; | 6 | struct list_head crst_list; |
6 | struct list_head pgtable_list; | 7 | struct list_head pgtable_list; |
7 | unsigned long asce_bits; | 8 | unsigned long asce_bits; |
diff --git a/arch/s390/include/asm/page.h b/arch/s390/include/asm/page.h index 3e3594d01f83..5e9daf5d7f22 100644 --- a/arch/s390/include/asm/page.h +++ b/arch/s390/include/asm/page.h | |||
@@ -125,8 +125,6 @@ page_get_storage_key(unsigned long addr) | |||
125 | return skey; | 125 | return skey; |
126 | } | 126 | } |
127 | 127 | ||
128 | #ifdef CONFIG_PAGE_STATES | ||
129 | |||
130 | struct page; | 128 | struct page; |
131 | void arch_free_page(struct page *page, int order); | 129 | void arch_free_page(struct page *page, int order); |
132 | void arch_alloc_page(struct page *page, int order); | 130 | void arch_alloc_page(struct page *page, int order); |
@@ -134,8 +132,6 @@ void arch_alloc_page(struct page *page, int order); | |||
134 | #define HAVE_ARCH_FREE_PAGE | 132 | #define HAVE_ARCH_FREE_PAGE |
135 | #define HAVE_ARCH_ALLOC_PAGE | 133 | #define HAVE_ARCH_ALLOC_PAGE |
136 | 134 | ||
137 | #endif | ||
138 | |||
139 | #endif /* !__ASSEMBLY__ */ | 135 | #endif /* !__ASSEMBLY__ */ |
140 | 136 | ||
141 | #define __PAGE_OFFSET 0x0UL | 137 | #define __PAGE_OFFSET 0x0UL |
diff --git a/arch/s390/include/asm/pgalloc.h b/arch/s390/include/asm/pgalloc.h index b2658b9220fe..ddad5903341c 100644 --- a/arch/s390/include/asm/pgalloc.h +++ b/arch/s390/include/asm/pgalloc.h | |||
@@ -140,6 +140,7 @@ static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) | |||
140 | 140 | ||
141 | static inline pgd_t *pgd_alloc(struct mm_struct *mm) | 141 | static inline pgd_t *pgd_alloc(struct mm_struct *mm) |
142 | { | 142 | { |
143 | spin_lock_init(&mm->context.list_lock); | ||
143 | INIT_LIST_HEAD(&mm->context.crst_list); | 144 | INIT_LIST_HEAD(&mm->context.crst_list); |
144 | INIT_LIST_HEAD(&mm->context.pgtable_list); | 145 | INIT_LIST_HEAD(&mm->context.pgtable_list); |
145 | return (pgd_t *) crst_table_alloc(mm, s390_noexec); | 146 | return (pgd_t *) crst_table_alloc(mm, s390_noexec); |
diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h index c139fa7b8e89..cf8eed3fa779 100644 --- a/arch/s390/include/asm/processor.h +++ b/arch/s390/include/asm/processor.h | |||
@@ -14,7 +14,7 @@ | |||
14 | #define __ASM_S390_PROCESSOR_H | 14 | #define __ASM_S390_PROCESSOR_H |
15 | 15 | ||
16 | #include <linux/linkage.h> | 16 | #include <linux/linkage.h> |
17 | #include <asm/cpuid.h> | 17 | #include <asm/cpu.h> |
18 | #include <asm/page.h> | 18 | #include <asm/page.h> |
19 | #include <asm/ptrace.h> | 19 | #include <asm/ptrace.h> |
20 | #include <asm/setup.h> | 20 | #include <asm/setup.h> |
@@ -26,7 +26,7 @@ | |||
26 | */ | 26 | */ |
27 | #define current_text_addr() ({ void *pc; asm("basr %0,0" : "=a" (pc)); pc; }) | 27 | #define current_text_addr() ({ void *pc; asm("basr %0,0" : "=a" (pc)); pc; }) |
28 | 28 | ||
29 | static inline void get_cpu_id(cpuid_t *ptr) | 29 | static inline void get_cpu_id(struct cpuid *ptr) |
30 | { | 30 | { |
31 | asm volatile("stidp 0(%1)" : "=m" (*ptr) : "a" (ptr)); | 31 | asm volatile("stidp 0(%1)" : "=m" (*ptr) : "a" (ptr)); |
32 | } | 32 | } |
diff --git a/arch/s390/include/asm/scatterlist.h b/arch/s390/include/asm/scatterlist.h index 29ec8e28c8df..35d786fe93ae 100644 --- a/arch/s390/include/asm/scatterlist.h +++ b/arch/s390/include/asm/scatterlist.h | |||
@@ -1,19 +1 @@ | |||
1 | #ifndef _ASMS390_SCATTERLIST_H | #include <asm-generic/scatterlist.h> | |
2 | #define _ASMS390_SCATTERLIST_H | ||
3 | |||
4 | struct scatterlist { | ||
5 | #ifdef CONFIG_DEBUG_SG | ||
6 | unsigned long sg_magic; | ||
7 | #endif | ||
8 | unsigned long page_link; | ||
9 | unsigned int offset; | ||
10 | unsigned int length; | ||
11 | }; | ||
12 | |||
13 | #ifdef __s390x__ | ||
14 | #define ISA_DMA_THRESHOLD (0xffffffffffffffffUL) | ||
15 | #else | ||
16 | #define ISA_DMA_THRESHOLD (0xffffffffUL) | ||
17 | #endif | ||
18 | |||
19 | #endif /* _ASMS390X_SCATTERLIST_H */ | ||
diff --git a/arch/s390/include/asm/scsw.h b/arch/s390/include/asm/scsw.h new file mode 100644 index 000000000000..de389cb54d28 --- /dev/null +++ b/arch/s390/include/asm/scsw.h | |||
@@ -0,0 +1,956 @@ | |||
1 | /* | ||
2 | * Helper functions for scsw access. | ||
3 | * | ||
4 | * Copyright IBM Corp. 2008,2009 | ||
5 | * Author(s): Peter Oberparleiter <peter.oberparleiter@de.ibm.com> | ||
6 | */ | ||
7 | |||
8 | #ifndef _ASM_S390_SCSW_H_ | ||
9 | #define _ASM_S390_SCSW_H_ | ||
10 | |||
11 | #include <linux/types.h> | ||
12 | #include <asm/chsc.h> | ||
13 | #include <asm/cio.h> | ||
14 | |||
15 | /** | ||
16 | * struct cmd_scsw - command-mode subchannel status word | ||
17 | * @key: subchannel key | ||
18 | * @sctl: suspend control | ||
19 | * @eswf: esw format | ||
20 | * @cc: deferred condition code | ||
21 | * @fmt: format | ||
22 | * @pfch: prefetch | ||
23 | * @isic: initial-status interruption control | ||
24 | * @alcc: address-limit checking control | ||
25 | * @ssi: suppress-suspended interruption | ||
26 | * @zcc: zero condition code | ||
27 | * @ectl: extended control | ||
28 | * @pno: path not operational | ||
29 | * @res: reserved | ||
30 | * @fctl: function control | ||
31 | * @actl: activity control | ||
32 | * @stctl: status control | ||
33 | * @cpa: channel program address | ||
34 | * @dstat: device status | ||
35 | * @cstat: subchannel status | ||
36 | * @count: residual count | ||
37 | */ | ||
38 | struct cmd_scsw { | ||
39 | __u32 key : 4; | ||
40 | __u32 sctl : 1; | ||
41 | __u32 eswf : 1; | ||
42 | __u32 cc : 2; | ||
43 | __u32 fmt : 1; | ||
44 | __u32 pfch : 1; | ||
45 | __u32 isic : 1; | ||
46 | __u32 alcc : 1; | ||
47 | __u32 ssi : 1; | ||
48 | __u32 zcc : 1; | ||
49 | __u32 ectl : 1; | ||
50 | __u32 pno : 1; | ||
51 | __u32 res : 1; | ||
52 | __u32 fctl : 3; | ||
53 | __u32 actl : 7; | ||
54 | __u32 stctl : 5; | ||
55 | __u32 cpa; | ||
56 | __u32 dstat : 8; | ||
57 | __u32 cstat : 8; | ||
58 | __u32 count : 16; | ||
59 | } __attribute__ ((packed)); | ||
60 | |||
61 | /** | ||
62 | * struct tm_scsw - transport-mode subchannel status word | ||
63 | * @key: subchannel key | ||
64 | * @eswf: esw format | ||
65 | * @cc: deferred condition code | ||
66 | * @fmt: format | ||
67 | * @x: IRB-format control | ||
68 | * @q: interrogate-complete | ||
69 | * @ectl: extended control | ||
70 | * @pno: path not operational | ||
71 | * @fctl: function control | ||
72 | * @actl: activity control | ||
73 | * @stctl: status control | ||
74 | * @tcw: TCW address | ||
75 | * @dstat: device status | ||
76 | * @cstat: subchannel status | ||
77 | * @fcxs: FCX status | ||
78 | * @schxs: subchannel-extended status | ||
79 | */ | ||
80 | struct tm_scsw { | ||
81 | u32 key:4; | ||
82 | u32 :1; | ||
83 | u32 eswf:1; | ||
84 | u32 cc:2; | ||
85 | u32 fmt:3; | ||
86 | u32 x:1; | ||
87 | u32 q:1; | ||
88 | u32 :1; | ||
89 | u32 ectl:1; | ||
90 | u32 pno:1; | ||
91 | u32 :1; | ||
92 | u32 fctl:3; | ||
93 | u32 actl:7; | ||
94 | u32 stctl:5; | ||
95 | u32 tcw; | ||
96 | u32 dstat:8; | ||
97 | u32 cstat:8; | ||
98 | u32 fcxs:8; | ||
99 | u32 schxs:8; | ||
100 | } __attribute__ ((packed)); | ||
101 | |||
102 | /** | ||
103 | * union scsw - subchannel status word | ||
104 | * @cmd: command-mode SCSW | ||
105 | * @tm: transport-mode SCSW | ||
106 | */ | ||
107 | union scsw { | ||
108 | struct cmd_scsw cmd; | ||
109 | struct tm_scsw tm; | ||
110 | } __attribute__ ((packed)); | ||
111 | |||
112 | #define SCSW_FCTL_CLEAR_FUNC 0x1 | ||
113 | #define SCSW_FCTL_HALT_FUNC 0x2 | ||
114 | #define SCSW_FCTL_START_FUNC 0x4 | ||
115 | |||
116 | #define SCSW_ACTL_SUSPENDED 0x1 | ||
117 | #define SCSW_ACTL_DEVACT 0x2 | ||
118 | #define SCSW_ACTL_SCHACT 0x4 | ||
119 | #define SCSW_ACTL_CLEAR_PEND 0x8 | ||
120 | #define SCSW_ACTL_HALT_PEND 0x10 | ||
121 | #define SCSW_ACTL_START_PEND 0x20 | ||
122 | #define SCSW_ACTL_RESUME_PEND 0x40 | ||
123 | |||
124 | #define SCSW_STCTL_STATUS_PEND 0x1 | ||
125 | #define SCSW_STCTL_SEC_STATUS 0x2 | ||
126 | #define SCSW_STCTL_PRIM_STATUS 0x4 | ||
127 | #define SCSW_STCTL_INTER_STATUS 0x8 | ||
128 | #define SCSW_STCTL_ALERT_STATUS 0x10 | ||
129 | |||
130 | #define DEV_STAT_ATTENTION 0x80 | ||
131 | #define DEV_STAT_STAT_MOD 0x40 | ||
132 | #define DEV_STAT_CU_END 0x20 | ||
133 | #define DEV_STAT_BUSY 0x10 | ||
134 | #define DEV_STAT_CHN_END 0x08 | ||
135 | #define DEV_STAT_DEV_END 0x04 | ||
136 | #define DEV_STAT_UNIT_CHECK 0x02 | ||
137 | #define DEV_STAT_UNIT_EXCEP 0x01 | ||
138 | |||
139 | #define SCHN_STAT_PCI 0x80 | ||
140 | #define SCHN_STAT_INCORR_LEN 0x40 | ||
141 | #define SCHN_STAT_PROG_CHECK 0x20 | ||
142 | #define SCHN_STAT_PROT_CHECK 0x10 | ||
143 | #define SCHN_STAT_CHN_DATA_CHK 0x08 | ||
144 | #define SCHN_STAT_CHN_CTRL_CHK 0x04 | ||
145 | #define SCHN_STAT_INTF_CTRL_CHK 0x02 | ||
146 | #define SCHN_STAT_CHAIN_CHECK 0x01 | ||
147 | |||
148 | /* | ||
149 | * architectured values for first sense byte | ||
150 | */ | ||
151 | #define SNS0_CMD_REJECT 0x80 | ||
152 | #define SNS_CMD_REJECT SNS0_CMD_REJEC | ||
153 | #define SNS0_INTERVENTION_REQ 0x40 | ||
154 | #define SNS0_BUS_OUT_CHECK 0x20 | ||
155 | #define SNS0_EQUIPMENT_CHECK 0x10 | ||
156 | #define SNS0_DATA_CHECK 0x08 | ||
157 | #define SNS0_OVERRUN 0x04 | ||
158 | #define SNS0_INCOMPL_DOMAIN 0x01 | ||
159 | |||
160 | /* | ||
161 | * architectured values for second sense byte | ||
162 | */ | ||
163 | #define SNS1_PERM_ERR 0x80 | ||
164 | #define SNS1_INV_TRACK_FORMAT 0x40 | ||
165 | #define SNS1_EOC 0x20 | ||
166 | #define SNS1_MESSAGE_TO_OPER 0x10 | ||
167 | #define SNS1_NO_REC_FOUND 0x08 | ||
168 | #define SNS1_FILE_PROTECTED 0x04 | ||
169 | #define SNS1_WRITE_INHIBITED 0x02 | ||
170 | #define SNS1_INPRECISE_END 0x01 | ||
171 | |||
172 | /* | ||
173 | * architectured values for third sense byte | ||
174 | */ | ||
175 | #define SNS2_REQ_INH_WRITE 0x80 | ||
176 | #define SNS2_CORRECTABLE 0x40 | ||
177 | #define SNS2_FIRST_LOG_ERR 0x20 | ||
178 | #define SNS2_ENV_DATA_PRESENT 0x10 | ||
179 | #define SNS2_INPRECISE_END 0x04 | ||
180 | |||
181 | /** | ||
182 | * scsw_is_tm - check for transport mode scsw | ||
183 | * @scsw: pointer to scsw | ||
184 | * | ||
185 | * Return non-zero if the specified scsw is a transport mode scsw, zero | ||
186 | * otherwise. | ||
187 | */ | ||
188 | static inline int scsw_is_tm(union scsw *scsw) | ||
189 | { | ||
190 | return css_general_characteristics.fcx && (scsw->tm.x == 1); | ||
191 | } | ||
192 | |||
193 | /** | ||
194 | * scsw_key - return scsw key field | ||
195 | * @scsw: pointer to scsw | ||
196 | * | ||
197 | * Return the value of the key field of the specified scsw, regardless of | ||
198 | * whether it is a transport mode or command mode scsw. | ||
199 | */ | ||
200 | static inline u32 scsw_key(union scsw *scsw) | ||
201 | { | ||
202 | if (scsw_is_tm(scsw)) | ||
203 | return scsw->tm.key; | ||
204 | else | ||
205 | return scsw->cmd.key; | ||
206 | } | ||
207 | |||
208 | /** | ||
209 | * scsw_eswf - return scsw eswf field | ||
210 | * @scsw: pointer to scsw | ||
211 | * | ||
212 | * Return the value of the eswf field of the specified scsw, regardless of | ||
213 | * whether it is a transport mode or command mode scsw. | ||
214 | */ | ||
215 | static inline u32 scsw_eswf(union scsw *scsw) | ||
216 | { | ||
217 | if (scsw_is_tm(scsw)) | ||
218 | return scsw->tm.eswf; | ||
219 | else | ||
220 | return scsw->cmd.eswf; | ||
221 | } | ||
222 | |||
223 | /** | ||
224 | * scsw_cc - return scsw cc field | ||
225 | * @scsw: pointer to scsw | ||
226 | * | ||
227 | * Return the value of the cc field of the specified scsw, regardless of | ||
228 | * whether it is a transport mode or command mode scsw. | ||
229 | */ | ||
230 | static inline u32 scsw_cc(union scsw *scsw) | ||
231 | { | ||
232 | if (scsw_is_tm(scsw)) | ||
233 | return scsw->tm.cc; | ||
234 | else | ||
235 | return scsw->cmd.cc; | ||
236 | } | ||
237 | |||
238 | /** | ||
239 | * scsw_ectl - return scsw ectl field | ||
240 | * @scsw: pointer to scsw | ||
241 | * | ||
242 | * Return the value of the ectl field of the specified scsw, regardless of | ||
243 | * whether it is a transport mode or command mode scsw. | ||
244 | */ | ||
245 | static inline u32 scsw_ectl(union scsw *scsw) | ||
246 | { | ||
247 | if (scsw_is_tm(scsw)) | ||
248 | return scsw->tm.ectl; | ||
249 | else | ||
250 | return scsw->cmd.ectl; | ||
251 | } | ||
252 | |||
253 | /** | ||
254 | * scsw_pno - return scsw pno field | ||
255 | * @scsw: pointer to scsw | ||
256 | * | ||
257 | * Return the value of the pno field of the specified scsw, regardless of | ||
258 | * whether it is a transport mode or command mode scsw. | ||
259 | */ | ||
260 | static inline u32 scsw_pno(union scsw *scsw) | ||
261 | { | ||
262 | if (scsw_is_tm(scsw)) | ||
263 | return scsw->tm.pno; | ||
264 | else | ||
265 | return scsw->cmd.pno; | ||
266 | } | ||
267 | |||
268 | /** | ||
269 | * scsw_fctl - return scsw fctl field | ||
270 | * @scsw: pointer to scsw | ||
271 | * | ||
272 | * Return the value of the fctl field of the specified scsw, regardless of | ||
273 | * whether it is a transport mode or command mode scsw. | ||
274 | */ | ||
275 | static inline u32 scsw_fctl(union scsw *scsw) | ||
276 | { | ||
277 | if (scsw_is_tm(scsw)) | ||
278 | return scsw->tm.fctl; | ||
279 | else | ||
280 | return scsw->cmd.fctl; | ||
281 | } | ||
282 | |||
283 | /** | ||
284 | * scsw_actl - return scsw actl field | ||
285 | * @scsw: pointer to scsw | ||
286 | * | ||
287 | * Return the value of the actl field of the specified scsw, regardless of | ||
288 | * whether it is a transport mode or command mode scsw. | ||
289 | */ | ||
290 | static inline u32 scsw_actl(union scsw *scsw) | ||
291 | { | ||
292 | if (scsw_is_tm(scsw)) | ||
293 | return scsw->tm.actl; | ||
294 | else | ||
295 | return scsw->cmd.actl; | ||
296 | } | ||
297 | |||
298 | /** | ||
299 | * scsw_stctl - return scsw stctl field | ||
300 | * @scsw: pointer to scsw | ||
301 | * | ||
302 | * Return the value of the stctl field of the specified scsw, regardless of | ||
303 | * whether it is a transport mode or command mode scsw. | ||
304 | */ | ||
305 | static inline u32 scsw_stctl(union scsw *scsw) | ||
306 | { | ||
307 | if (scsw_is_tm(scsw)) | ||
308 | return scsw->tm.stctl; | ||
309 | else | ||
310 | return scsw->cmd.stctl; | ||
311 | } | ||
312 | |||
313 | /** | ||
314 | * scsw_dstat - return scsw dstat field | ||
315 | * @scsw: pointer to scsw | ||
316 | * | ||
317 | * Return the value of the dstat field of the specified scsw, regardless of | ||
318 | * whether it is a transport mode or command mode scsw. | ||
319 | */ | ||
320 | static inline u32 scsw_dstat(union scsw *scsw) | ||
321 | { | ||
322 | if (scsw_is_tm(scsw)) | ||
323 | return scsw->tm.dstat; | ||
324 | else | ||
325 | return scsw->cmd.dstat; | ||
326 | } | ||
327 | |||
328 | /** | ||
329 | * scsw_cstat - return scsw cstat field | ||
330 | * @scsw: pointer to scsw | ||
331 | * | ||
332 | * Return the value of the cstat field of the specified scsw, regardless of | ||
333 | * whether it is a transport mode or command mode scsw. | ||
334 | */ | ||
335 | static inline u32 scsw_cstat(union scsw *scsw) | ||
336 | { | ||
337 | if (scsw_is_tm(scsw)) | ||
338 | return scsw->tm.cstat; | ||
339 | else | ||
340 | return scsw->cmd.cstat; | ||
341 | } | ||
342 | |||
343 | /** | ||
344 | * scsw_cmd_is_valid_key - check key field validity | ||
345 | * @scsw: pointer to scsw | ||
346 | * | ||
347 | * Return non-zero if the key field of the specified command mode scsw is | ||
348 | * valid, zero otherwise. | ||
349 | */ | ||
350 | static inline int scsw_cmd_is_valid_key(union scsw *scsw) | ||
351 | { | ||
352 | return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC); | ||
353 | } | ||
354 | |||
355 | /** | ||
356 | * scsw_cmd_is_valid_sctl - check fctl field validity | ||
357 | * @scsw: pointer to scsw | ||
358 | * | ||
359 | * Return non-zero if the fctl field of the specified command mode scsw is | ||
360 | * valid, zero otherwise. | ||
361 | */ | ||
362 | static inline int scsw_cmd_is_valid_sctl(union scsw *scsw) | ||
363 | { | ||
364 | return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC); | ||
365 | } | ||
366 | |||
367 | /** | ||
368 | * scsw_cmd_is_valid_eswf - check eswf field validity | ||
369 | * @scsw: pointer to scsw | ||
370 | * | ||
371 | * Return non-zero if the eswf field of the specified command mode scsw is | ||
372 | * valid, zero otherwise. | ||
373 | */ | ||
374 | static inline int scsw_cmd_is_valid_eswf(union scsw *scsw) | ||
375 | { | ||
376 | return (scsw->cmd.stctl & SCSW_STCTL_STATUS_PEND); | ||
377 | } | ||
378 | |||
379 | /** | ||
380 | * scsw_cmd_is_valid_cc - check cc field validity | ||
381 | * @scsw: pointer to scsw | ||
382 | * | ||
383 | * Return non-zero if the cc field of the specified command mode scsw is | ||
384 | * valid, zero otherwise. | ||
385 | */ | ||
386 | static inline int scsw_cmd_is_valid_cc(union scsw *scsw) | ||
387 | { | ||
388 | return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC) && | ||
389 | (scsw->cmd.stctl & SCSW_STCTL_STATUS_PEND); | ||
390 | } | ||
391 | |||
392 | /** | ||
393 | * scsw_cmd_is_valid_fmt - check fmt field validity | ||
394 | * @scsw: pointer to scsw | ||
395 | * | ||
396 | * Return non-zero if the fmt field of the specified command mode scsw is | ||
397 | * valid, zero otherwise. | ||
398 | */ | ||
399 | static inline int scsw_cmd_is_valid_fmt(union scsw *scsw) | ||
400 | { | ||
401 | return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC); | ||
402 | } | ||
403 | |||
404 | /** | ||
405 | * scsw_cmd_is_valid_pfch - check pfch field validity | ||
406 | * @scsw: pointer to scsw | ||
407 | * | ||
408 | * Return non-zero if the pfch field of the specified command mode scsw is | ||
409 | * valid, zero otherwise. | ||
410 | */ | ||
411 | static inline int scsw_cmd_is_valid_pfch(union scsw *scsw) | ||
412 | { | ||
413 | return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC); | ||
414 | } | ||
415 | |||
416 | /** | ||
417 | * scsw_cmd_is_valid_isic - check isic field validity | ||
418 | * @scsw: pointer to scsw | ||
419 | * | ||
420 | * Return non-zero if the isic field of the specified command mode scsw is | ||
421 | * valid, zero otherwise. | ||
422 | */ | ||
423 | static inline int scsw_cmd_is_valid_isic(union scsw *scsw) | ||
424 | { | ||
425 | return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC); | ||
426 | } | ||
427 | |||
428 | /** | ||
429 | * scsw_cmd_is_valid_alcc - check alcc field validity | ||
430 | * @scsw: pointer to scsw | ||
431 | * | ||
432 | * Return non-zero if the alcc field of the specified command mode scsw is | ||
433 | * valid, zero otherwise. | ||
434 | */ | ||
435 | static inline int scsw_cmd_is_valid_alcc(union scsw *scsw) | ||
436 | { | ||
437 | return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC); | ||
438 | } | ||
439 | |||
440 | /** | ||
441 | * scsw_cmd_is_valid_ssi - check ssi field validity | ||
442 | * @scsw: pointer to scsw | ||
443 | * | ||
444 | * Return non-zero if the ssi field of the specified command mode scsw is | ||
445 | * valid, zero otherwise. | ||
446 | */ | ||
447 | static inline int scsw_cmd_is_valid_ssi(union scsw *scsw) | ||
448 | { | ||
449 | return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC); | ||
450 | } | ||
451 | |||
452 | /** | ||
453 | * scsw_cmd_is_valid_zcc - check zcc field validity | ||
454 | * @scsw: pointer to scsw | ||
455 | * | ||
456 | * Return non-zero if the zcc field of the specified command mode scsw is | ||
457 | * valid, zero otherwise. | ||
458 | */ | ||
459 | static inline int scsw_cmd_is_valid_zcc(union scsw *scsw) | ||
460 | { | ||
461 | return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC) && | ||
462 | (scsw->cmd.stctl & SCSW_STCTL_INTER_STATUS); | ||
463 | } | ||
464 | |||
465 | /** | ||
466 | * scsw_cmd_is_valid_ectl - check ectl field validity | ||
467 | * @scsw: pointer to scsw | ||
468 | * | ||
469 | * Return non-zero if the ectl field of the specified command mode scsw is | ||
470 | * valid, zero otherwise. | ||
471 | */ | ||
472 | static inline int scsw_cmd_is_valid_ectl(union scsw *scsw) | ||
473 | { | ||
474 | return (scsw->cmd.stctl & SCSW_STCTL_STATUS_PEND) && | ||
475 | !(scsw->cmd.stctl & SCSW_STCTL_INTER_STATUS) && | ||
476 | (scsw->cmd.stctl & SCSW_STCTL_ALERT_STATUS); | ||
477 | } | ||
478 | |||
479 | /** | ||
480 | * scsw_cmd_is_valid_pno - check pno field validity | ||
481 | * @scsw: pointer to scsw | ||
482 | * | ||
483 | * Return non-zero if the pno field of the specified command mode scsw is | ||
484 | * valid, zero otherwise. | ||
485 | */ | ||
486 | static inline int scsw_cmd_is_valid_pno(union scsw *scsw) | ||
487 | { | ||
488 | return (scsw->cmd.fctl != 0) && | ||
489 | (scsw->cmd.stctl & SCSW_STCTL_STATUS_PEND) && | ||
490 | (!(scsw->cmd.stctl & SCSW_STCTL_INTER_STATUS) || | ||
491 | ((scsw->cmd.stctl & SCSW_STCTL_INTER_STATUS) && | ||
492 | (scsw->cmd.actl & SCSW_ACTL_SUSPENDED))); | ||
493 | } | ||
494 | |||
495 | /** | ||
496 | * scsw_cmd_is_valid_fctl - check fctl field validity | ||
497 | * @scsw: pointer to scsw | ||
498 | * | ||
499 | * Return non-zero if the fctl field of the specified command mode scsw is | ||
500 | * valid, zero otherwise. | ||
501 | */ | ||
502 | static inline int scsw_cmd_is_valid_fctl(union scsw *scsw) | ||
503 | { | ||
504 | /* Only valid if pmcw.dnv == 1*/ | ||
505 | return 1; | ||
506 | } | ||
507 | |||
508 | /** | ||
509 | * scsw_cmd_is_valid_actl - check actl field validity | ||
510 | * @scsw: pointer to scsw | ||
511 | * | ||
512 | * Return non-zero if the actl field of the specified command mode scsw is | ||
513 | * valid, zero otherwise. | ||
514 | */ | ||
515 | static inline int scsw_cmd_is_valid_actl(union scsw *scsw) | ||
516 | { | ||
517 | /* Only valid if pmcw.dnv == 1*/ | ||
518 | return 1; | ||
519 | } | ||
520 | |||
521 | /** | ||
522 | * scsw_cmd_is_valid_stctl - check stctl field validity | ||
523 | * @scsw: pointer to scsw | ||
524 | * | ||
525 | * Return non-zero if the stctl field of the specified command mode scsw is | ||
526 | * valid, zero otherwise. | ||
527 | */ | ||
528 | static inline int scsw_cmd_is_valid_stctl(union scsw *scsw) | ||
529 | { | ||
530 | /* Only valid if pmcw.dnv == 1*/ | ||
531 | return 1; | ||
532 | } | ||
533 | |||
534 | /** | ||
535 | * scsw_cmd_is_valid_dstat - check dstat field validity | ||
536 | * @scsw: pointer to scsw | ||
537 | * | ||
538 | * Return non-zero if the dstat field of the specified command mode scsw is | ||
539 | * valid, zero otherwise. | ||
540 | */ | ||
541 | static inline int scsw_cmd_is_valid_dstat(union scsw *scsw) | ||
542 | { | ||
543 | return (scsw->cmd.stctl & SCSW_STCTL_STATUS_PEND) && | ||
544 | (scsw->cmd.cc != 3); | ||
545 | } | ||
546 | |||
547 | /** | ||
548 | * scsw_cmd_is_valid_cstat - check cstat field validity | ||
549 | * @scsw: pointer to scsw | ||
550 | * | ||
551 | * Return non-zero if the cstat field of the specified command mode scsw is | ||
552 | * valid, zero otherwise. | ||
553 | */ | ||
554 | static inline int scsw_cmd_is_valid_cstat(union scsw *scsw) | ||
555 | { | ||
556 | return (scsw->cmd.stctl & SCSW_STCTL_STATUS_PEND) && | ||
557 | (scsw->cmd.cc != 3); | ||
558 | } | ||
559 | |||
560 | /** | ||
561 | * scsw_tm_is_valid_key - check key field validity | ||
562 | * @scsw: pointer to scsw | ||
563 | * | ||
564 | * Return non-zero if the key field of the specified transport mode scsw is | ||
565 | * valid, zero otherwise. | ||
566 | */ | ||
567 | static inline int scsw_tm_is_valid_key(union scsw *scsw) | ||
568 | { | ||
569 | return (scsw->tm.fctl & SCSW_FCTL_START_FUNC); | ||
570 | } | ||
571 | |||
572 | /** | ||
573 | * scsw_tm_is_valid_eswf - check eswf field validity | ||
574 | * @scsw: pointer to scsw | ||
575 | * | ||
576 | * Return non-zero if the eswf field of the specified transport mode scsw is | ||
577 | * valid, zero otherwise. | ||
578 | */ | ||
579 | static inline int scsw_tm_is_valid_eswf(union scsw *scsw) | ||
580 | { | ||
581 | return (scsw->tm.stctl & SCSW_STCTL_STATUS_PEND); | ||
582 | } | ||
583 | |||
584 | /** | ||
585 | * scsw_tm_is_valid_cc - check cc field validity | ||
586 | * @scsw: pointer to scsw | ||
587 | * | ||
588 | * Return non-zero if the cc field of the specified transport mode scsw is | ||
589 | * valid, zero otherwise. | ||
590 | */ | ||
591 | static inline int scsw_tm_is_valid_cc(union scsw *scsw) | ||
592 | { | ||
593 | return (scsw->tm.fctl & SCSW_FCTL_START_FUNC) && | ||
594 | (scsw->tm.stctl & SCSW_STCTL_STATUS_PEND); | ||
595 | } | ||
596 | |||
597 | /** | ||
598 | * scsw_tm_is_valid_fmt - check fmt field validity | ||
599 | * @scsw: pointer to scsw | ||
600 | * | ||
601 | * Return non-zero if the fmt field of the specified transport mode scsw is | ||
602 | * valid, zero otherwise. | ||
603 | */ | ||
604 | static inline int scsw_tm_is_valid_fmt(union scsw *scsw) | ||
605 | { | ||
606 | return 1; | ||
607 | } | ||
608 | |||
609 | /** | ||
610 | * scsw_tm_is_valid_x - check x field validity | ||
611 | * @scsw: pointer to scsw | ||
612 | * | ||
613 | * Return non-zero if the x field of the specified transport mode scsw is | ||
614 | * valid, zero otherwise. | ||
615 | */ | ||
616 | static inline int scsw_tm_is_valid_x(union scsw *scsw) | ||
617 | { | ||
618 | return 1; | ||
619 | } | ||
620 | |||
621 | /** | ||
622 | * scsw_tm_is_valid_q - check q field validity | ||
623 | * @scsw: pointer to scsw | ||
624 | * | ||
625 | * Return non-zero if the q field of the specified transport mode scsw is | ||
626 | * valid, zero otherwise. | ||
627 | */ | ||
628 | static inline int scsw_tm_is_valid_q(union scsw *scsw) | ||
629 | { | ||
630 | return 1; | ||
631 | } | ||
632 | |||
633 | /** | ||
634 | * scsw_tm_is_valid_ectl - check ectl field validity | ||
635 | * @scsw: pointer to scsw | ||
636 | * | ||
637 | * Return non-zero if the ectl field of the specified transport mode scsw is | ||
638 | * valid, zero otherwise. | ||
639 | */ | ||
640 | static inline int scsw_tm_is_valid_ectl(union scsw *scsw) | ||
641 | { | ||
642 | return (scsw->tm.stctl & SCSW_STCTL_STATUS_PEND) && | ||
643 | !(scsw->tm.stctl & SCSW_STCTL_INTER_STATUS) && | ||
644 | (scsw->tm.stctl & SCSW_STCTL_ALERT_STATUS); | ||
645 | } | ||
646 | |||
647 | /** | ||
648 | * scsw_tm_is_valid_pno - check pno field validity | ||
649 | * @scsw: pointer to scsw | ||
650 | * | ||
651 | * Return non-zero if the pno field of the specified transport mode scsw is | ||
652 | * valid, zero otherwise. | ||
653 | */ | ||
654 | static inline int scsw_tm_is_valid_pno(union scsw *scsw) | ||
655 | { | ||
656 | return (scsw->tm.fctl != 0) && | ||
657 | (scsw->tm.stctl & SCSW_STCTL_STATUS_PEND) && | ||
658 | (!(scsw->tm.stctl & SCSW_STCTL_INTER_STATUS) || | ||
659 | ((scsw->tm.stctl & SCSW_STCTL_INTER_STATUS) && | ||
660 | (scsw->tm.actl & SCSW_ACTL_SUSPENDED))); | ||
661 | } | ||
662 | |||
663 | /** | ||
664 | * scsw_tm_is_valid_fctl - check fctl field validity | ||
665 | * @scsw: pointer to scsw | ||
666 | * | ||
667 | * Return non-zero if the fctl field of the specified transport mode scsw is | ||
668 | * valid, zero otherwise. | ||
669 | */ | ||
670 | static inline int scsw_tm_is_valid_fctl(union scsw *scsw) | ||
671 | { | ||
672 | /* Only valid if pmcw.dnv == 1*/ | ||
673 | return 1; | ||
674 | } | ||
675 | |||
676 | /** | ||
677 | * scsw_tm_is_valid_actl - check actl field validity | ||
678 | * @scsw: pointer to scsw | ||
679 | * | ||
680 | * Return non-zero if the actl field of the specified transport mode scsw is | ||
681 | * valid, zero otherwise. | ||
682 | */ | ||
683 | static inline int scsw_tm_is_valid_actl(union scsw *scsw) | ||
684 | { | ||
685 | /* Only valid if pmcw.dnv == 1*/ | ||
686 | return 1; | ||
687 | } | ||
688 | |||
689 | /** | ||
690 | * scsw_tm_is_valid_stctl - check stctl field validity | ||
691 | * @scsw: pointer to scsw | ||
692 | * | ||
693 | * Return non-zero if the stctl field of the specified transport mode scsw is | ||
694 | * valid, zero otherwise. | ||
695 | */ | ||
696 | static inline int scsw_tm_is_valid_stctl(union scsw *scsw) | ||
697 | { | ||
698 | /* Only valid if pmcw.dnv == 1*/ | ||
699 | return 1; | ||
700 | } | ||
701 | |||
702 | /** | ||
703 | * scsw_tm_is_valid_dstat - check dstat field validity | ||
704 | * @scsw: pointer to scsw | ||
705 | * | ||
706 | * Return non-zero if the dstat field of the specified transport mode scsw is | ||
707 | * valid, zero otherwise. | ||
708 | */ | ||
709 | static inline int scsw_tm_is_valid_dstat(union scsw *scsw) | ||
710 | { | ||
711 | return (scsw->tm.stctl & SCSW_STCTL_STATUS_PEND) && | ||
712 | (scsw->tm.cc != 3); | ||
713 | } | ||
714 | |||
715 | /** | ||
716 | * scsw_tm_is_valid_cstat - check cstat field validity | ||
717 | * @scsw: pointer to scsw | ||
718 | * | ||
719 | * Return non-zero if the cstat field of the specified transport mode scsw is | ||
720 | * valid, zero otherwise. | ||
721 | */ | ||
722 | static inline int scsw_tm_is_valid_cstat(union scsw *scsw) | ||
723 | { | ||
724 | return (scsw->tm.stctl & SCSW_STCTL_STATUS_PEND) && | ||
725 | (scsw->tm.cc != 3); | ||
726 | } | ||
727 | |||
728 | /** | ||
729 | * scsw_tm_is_valid_fcxs - check fcxs field validity | ||
730 | * @scsw: pointer to scsw | ||
731 | * | ||
732 | * Return non-zero if the fcxs field of the specified transport mode scsw is | ||
733 | * valid, zero otherwise. | ||
734 | */ | ||
735 | static inline int scsw_tm_is_valid_fcxs(union scsw *scsw) | ||
736 | { | ||
737 | return 1; | ||
738 | } | ||
739 | |||
740 | /** | ||
741 | * scsw_tm_is_valid_schxs - check schxs field validity | ||
742 | * @scsw: pointer to scsw | ||
743 | * | ||
744 | * Return non-zero if the schxs field of the specified transport mode scsw is | ||
745 | * valid, zero otherwise. | ||
746 | */ | ||
747 | static inline int scsw_tm_is_valid_schxs(union scsw *scsw) | ||
748 | { | ||
749 | return (scsw->tm.cstat & (SCHN_STAT_PROG_CHECK | | ||
750 | SCHN_STAT_INTF_CTRL_CHK | | ||
751 | SCHN_STAT_PROT_CHECK | | ||
752 | SCHN_STAT_CHN_DATA_CHK)); | ||
753 | } | ||
754 | |||
755 | /** | ||
756 | * scsw_is_valid_actl - check actl field validity | ||
757 | * @scsw: pointer to scsw | ||
758 | * | ||
759 | * Return non-zero if the actl field of the specified scsw is valid, | ||
760 | * regardless of whether it is a transport mode or command mode scsw. | ||
761 | * Return zero if the field does not contain a valid value. | ||
762 | */ | ||
763 | static inline int scsw_is_valid_actl(union scsw *scsw) | ||
764 | { | ||
765 | if (scsw_is_tm(scsw)) | ||
766 | return scsw_tm_is_valid_actl(scsw); | ||
767 | else | ||
768 | return scsw_cmd_is_valid_actl(scsw); | ||
769 | } | ||
770 | |||
771 | /** | ||
772 | * scsw_is_valid_cc - check cc field validity | ||
773 | * @scsw: pointer to scsw | ||
774 | * | ||
775 | * Return non-zero if the cc field of the specified scsw is valid, | ||
776 | * regardless of whether it is a transport mode or command mode scsw. | ||
777 | * Return zero if the field does not contain a valid value. | ||
778 | */ | ||
779 | static inline int scsw_is_valid_cc(union scsw *scsw) | ||
780 | { | ||
781 | if (scsw_is_tm(scsw)) | ||
782 | return scsw_tm_is_valid_cc(scsw); | ||
783 | else | ||
784 | return scsw_cmd_is_valid_cc(scsw); | ||
785 | } | ||
786 | |||
787 | /** | ||
788 | * scsw_is_valid_cstat - check cstat field validity | ||
789 | * @scsw: pointer to scsw | ||
790 | * | ||
791 | * Return non-zero if the cstat field of the specified scsw is valid, | ||
792 | * regardless of whether it is a transport mode or command mode scsw. | ||
793 | * Return zero if the field does not contain a valid value. | ||
794 | */ | ||
795 | static inline int scsw_is_valid_cstat(union scsw *scsw) | ||
796 | { | ||
797 | if (scsw_is_tm(scsw)) | ||
798 | return scsw_tm_is_valid_cstat(scsw); | ||
799 | else | ||
800 | return scsw_cmd_is_valid_cstat(scsw); | ||
801 | } | ||
802 | |||
803 | /** | ||
804 | * scsw_is_valid_dstat - check dstat field validity | ||
805 | * @scsw: pointer to scsw | ||
806 | * | ||
807 | * Return non-zero if the dstat field of the specified scsw is valid, | ||
808 | * regardless of whether it is a transport mode or command mode scsw. | ||
809 | * Return zero if the field does not contain a valid value. | ||
810 | */ | ||
811 | static inline int scsw_is_valid_dstat(union scsw *scsw) | ||
812 | { | ||
813 | if (scsw_is_tm(scsw)) | ||
814 | return scsw_tm_is_valid_dstat(scsw); | ||
815 | else | ||
816 | return scsw_cmd_is_valid_dstat(scsw); | ||
817 | } | ||
818 | |||
819 | /** | ||
820 | * scsw_is_valid_ectl - check ectl field validity | ||
821 | * @scsw: pointer to scsw | ||
822 | * | ||
823 | * Return non-zero if the ectl field of the specified scsw is valid, | ||
824 | * regardless of whether it is a transport mode or command mode scsw. | ||
825 | * Return zero if the field does not contain a valid value. | ||
826 | */ | ||
827 | static inline int scsw_is_valid_ectl(union scsw *scsw) | ||
828 | { | ||
829 | if (scsw_is_tm(scsw)) | ||
830 | return scsw_tm_is_valid_ectl(scsw); | ||
831 | else | ||
832 | return scsw_cmd_is_valid_ectl(scsw); | ||
833 | } | ||
834 | |||
835 | /** | ||
836 | * scsw_is_valid_eswf - check eswf field validity | ||
837 | * @scsw: pointer to scsw | ||
838 | * | ||
839 | * Return non-zero if the eswf field of the specified scsw is valid, | ||
840 | * regardless of whether it is a transport mode or command mode scsw. | ||
841 | * Return zero if the field does not contain a valid value. | ||
842 | */ | ||
843 | static inline int scsw_is_valid_eswf(union scsw *scsw) | ||
844 | { | ||
845 | if (scsw_is_tm(scsw)) | ||
846 | return scsw_tm_is_valid_eswf(scsw); | ||
847 | else | ||
848 | return scsw_cmd_is_valid_eswf(scsw); | ||
849 | } | ||
850 | |||
851 | /** | ||
852 | * scsw_is_valid_fctl - check fctl field validity | ||
853 | * @scsw: pointer to scsw | ||
854 | * | ||
855 | * Return non-zero if the fctl field of the specified scsw is valid, | ||
856 | * regardless of whether it is a transport mode or command mode scsw. | ||
857 | * Return zero if the field does not contain a valid value. | ||
858 | */ | ||
859 | static inline int scsw_is_valid_fctl(union scsw *scsw) | ||
860 | { | ||
861 | if (scsw_is_tm(scsw)) | ||
862 | return scsw_tm_is_valid_fctl(scsw); | ||
863 | else | ||
864 | return scsw_cmd_is_valid_fctl(scsw); | ||
865 | } | ||
866 | |||
867 | /** | ||
868 | * scsw_is_valid_key - check key field validity | ||
869 | * @scsw: pointer to scsw | ||
870 | * | ||
871 | * Return non-zero if the key field of the specified scsw is valid, | ||
872 | * regardless of whether it is a transport mode or command mode scsw. | ||
873 | * Return zero if the field does not contain a valid value. | ||
874 | */ | ||
875 | static inline int scsw_is_valid_key(union scsw *scsw) | ||
876 | { | ||
877 | if (scsw_is_tm(scsw)) | ||
878 | return scsw_tm_is_valid_key(scsw); | ||
879 | else | ||
880 | return scsw_cmd_is_valid_key(scsw); | ||
881 | } | ||
882 | |||
883 | /** | ||
884 | * scsw_is_valid_pno - check pno field validity | ||
885 | * @scsw: pointer to scsw | ||
886 | * | ||
887 | * Return non-zero if the pno field of the specified scsw is valid, | ||
888 | * regardless of whether it is a transport mode or command mode scsw. | ||
889 | * Return zero if the field does not contain a valid value. | ||
890 | */ | ||
891 | static inline int scsw_is_valid_pno(union scsw *scsw) | ||
892 | { | ||
893 | if (scsw_is_tm(scsw)) | ||
894 | return scsw_tm_is_valid_pno(scsw); | ||
895 | else | ||
896 | return scsw_cmd_is_valid_pno(scsw); | ||
897 | } | ||
898 | |||
899 | /** | ||
900 | * scsw_is_valid_stctl - check stctl field validity | ||
901 | * @scsw: pointer to scsw | ||
902 | * | ||
903 | * Return non-zero if the stctl field of the specified scsw is valid, | ||
904 | * regardless of whether it is a transport mode or command mode scsw. | ||
905 | * Return zero if the field does not contain a valid value. | ||
906 | */ | ||
907 | static inline int scsw_is_valid_stctl(union scsw *scsw) | ||
908 | { | ||
909 | if (scsw_is_tm(scsw)) | ||
910 | return scsw_tm_is_valid_stctl(scsw); | ||
911 | else | ||
912 | return scsw_cmd_is_valid_stctl(scsw); | ||
913 | } | ||
914 | |||
915 | /** | ||
916 | * scsw_cmd_is_solicited - check for solicited scsw | ||
917 | * @scsw: pointer to scsw | ||
918 | * | ||
919 | * Return non-zero if the command mode scsw indicates that the associated | ||
920 | * status condition is solicited, zero if it is unsolicited. | ||
921 | */ | ||
922 | static inline int scsw_cmd_is_solicited(union scsw *scsw) | ||
923 | { | ||
924 | return (scsw->cmd.cc != 0) || (scsw->cmd.stctl != | ||
925 | (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)); | ||
926 | } | ||
927 | |||
928 | /** | ||
929 | * scsw_tm_is_solicited - check for solicited scsw | ||
930 | * @scsw: pointer to scsw | ||
931 | * | ||
932 | * Return non-zero if the transport mode scsw indicates that the associated | ||
933 | * status condition is solicited, zero if it is unsolicited. | ||
934 | */ | ||
935 | static inline int scsw_tm_is_solicited(union scsw *scsw) | ||
936 | { | ||
937 | return (scsw->tm.cc != 0) || (scsw->tm.stctl != | ||
938 | (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)); | ||
939 | } | ||
940 | |||
941 | /** | ||
942 | * scsw_is_solicited - check for solicited scsw | ||
943 | * @scsw: pointer to scsw | ||
944 | * | ||
945 | * Return non-zero if the transport or command mode scsw indicates that the | ||
946 | * associated status condition is solicited, zero if it is unsolicited. | ||
947 | */ | ||
948 | static inline int scsw_is_solicited(union scsw *scsw) | ||
949 | { | ||
950 | if (scsw_is_tm(scsw)) | ||
951 | return scsw_tm_is_solicited(scsw); | ||
952 | else | ||
953 | return scsw_cmd_is_solicited(scsw); | ||
954 | } | ||
955 | |||
956 | #endif /* _ASM_S390_SCSW_H_ */ | ||
diff --git a/arch/s390/include/asm/setup.h b/arch/s390/include/asm/setup.h index 38b0fc221ed7..e37478e87286 100644 --- a/arch/s390/include/asm/setup.h +++ b/arch/s390/include/asm/setup.h | |||
@@ -8,7 +8,7 @@ | |||
8 | #ifndef _ASM_S390_SETUP_H | 8 | #ifndef _ASM_S390_SETUP_H |
9 | #define _ASM_S390_SETUP_H | 9 | #define _ASM_S390_SETUP_H |
10 | 10 | ||
11 | #define COMMAND_LINE_SIZE 1024 | 11 | #define COMMAND_LINE_SIZE 4096 |
12 | 12 | ||
13 | #define ARCH_COMMAND_LINE_SIZE 896 | 13 | #define ARCH_COMMAND_LINE_SIZE 896 |
14 | 14 | ||
diff --git a/arch/s390/include/asm/smp.h b/arch/s390/include/asm/smp.h index 72137bc907ac..c991fe6473c9 100644 --- a/arch/s390/include/asm/smp.h +++ b/arch/s390/include/asm/smp.h | |||
@@ -51,32 +51,7 @@ extern void machine_power_off_smp(void); | |||
51 | #define PROC_CHANGE_PENALTY 20 /* Schedule penalty */ | 51 | #define PROC_CHANGE_PENALTY 20 /* Schedule penalty */ |
52 | 52 | ||
53 | #define raw_smp_processor_id() (S390_lowcore.cpu_nr) | 53 | #define raw_smp_processor_id() (S390_lowcore.cpu_nr) |
54 | 54 | #define cpu_logical_map(cpu) (cpu) | |
55 | /* | ||
56 | * returns 1 if cpu is in stopped/check stopped state or not operational | ||
57 | * returns 0 otherwise | ||
58 | */ | ||
59 | static inline int | ||
60 | smp_cpu_not_running(int cpu) | ||
61 | { | ||
62 | __u32 status; | ||
63 | |||
64 | switch (signal_processor_ps(&status, 0, cpu, sigp_sense)) { | ||
65 | case sigp_order_code_accepted: | ||
66 | case sigp_status_stored: | ||
67 | /* Check for stopped and check stop state */ | ||
68 | if (status & 0x50) | ||
69 | return 1; | ||
70 | break; | ||
71 | case sigp_not_operational: | ||
72 | return 1; | ||
73 | default: | ||
74 | break; | ||
75 | } | ||
76 | return 0; | ||
77 | } | ||
78 | |||
79 | #define cpu_logical_map(cpu) (cpu) | ||
80 | 55 | ||
81 | extern int __cpu_disable (void); | 56 | extern int __cpu_disable (void); |
82 | extern void __cpu_die (unsigned int cpu); | 57 | extern void __cpu_die (unsigned int cpu); |
@@ -91,11 +66,6 @@ extern void arch_send_call_function_ipi(cpumask_t mask); | |||
91 | 66 | ||
92 | #endif | 67 | #endif |
93 | 68 | ||
94 | #ifndef CONFIG_SMP | ||
95 | #define hard_smp_processor_id() 0 | ||
96 | #define smp_cpu_not_running(cpu) 1 | ||
97 | #endif | ||
98 | |||
99 | #ifdef CONFIG_HOTPLUG_CPU | 69 | #ifdef CONFIG_HOTPLUG_CPU |
100 | extern int smp_rescan_cpus(void); | 70 | extern int smp_rescan_cpus(void); |
101 | #else | 71 | #else |
diff --git a/arch/s390/include/asm/system.h b/arch/s390/include/asm/system.h index 4fb83c1cdb77..379661d2f81a 100644 --- a/arch/s390/include/asm/system.h +++ b/arch/s390/include/asm/system.h | |||
@@ -109,11 +109,7 @@ extern void pfault_fini(void); | |||
109 | #define pfault_fini() do { } while (0) | 109 | #define pfault_fini() do { } while (0) |
110 | #endif /* CONFIG_PFAULT */ | 110 | #endif /* CONFIG_PFAULT */ |
111 | 111 | ||
112 | #ifdef CONFIG_PAGE_STATES | ||
113 | extern void cmma_init(void); | 112 | extern void cmma_init(void); |
114 | #else | ||
115 | static inline void cmma_init(void) { } | ||
116 | #endif | ||
117 | 113 | ||
118 | #define finish_arch_switch(prev) do { \ | 114 | #define finish_arch_switch(prev) do { \ |
119 | set_fs(current->thread.mm_segment); \ | 115 | set_fs(current->thread.mm_segment); \ |
diff --git a/arch/s390/include/asm/timex.h b/arch/s390/include/asm/timex.h index cc21e3e20fd7..24aa1cda20ad 100644 --- a/arch/s390/include/asm/timex.h +++ b/arch/s390/include/asm/timex.h | |||
@@ -90,4 +90,18 @@ unsigned long long monotonic_clock(void); | |||
90 | 90 | ||
91 | extern u64 sched_clock_base_cc; | 91 | extern u64 sched_clock_base_cc; |
92 | 92 | ||
93 | /** | ||
94 | * get_clock_monotonic - returns current time in clock rate units | ||
95 | * | ||
96 | * The caller must ensure that preemption is disabled. | ||
97 | * The clock and sched_clock_base get changed via stop_machine. | ||
98 | * Therefore preemption must be disabled when calling this | ||
99 | * function, otherwise the returned value is not guaranteed to | ||
100 | * be monotonic. | ||
101 | */ | ||
102 | static inline unsigned long long get_clock_monotonic(void) | ||
103 | { | ||
104 | return get_clock_xt() - sched_clock_base_cc; | ||
105 | } | ||
106 | |||
93 | #endif | 107 | #endif |
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile index c75ed43b1a18..c7be8e10b87e 100644 --- a/arch/s390/kernel/Makefile +++ b/arch/s390/kernel/Makefile | |||
@@ -32,7 +32,7 @@ extra-y += head.o init_task.o vmlinux.lds | |||
32 | 32 | ||
33 | obj-$(CONFIG_MODULES) += s390_ksyms.o module.o | 33 | obj-$(CONFIG_MODULES) += s390_ksyms.o module.o |
34 | obj-$(CONFIG_SMP) += smp.o topology.o | 34 | obj-$(CONFIG_SMP) += smp.o topology.o |
35 | 35 | obj-$(CONFIG_HIBERNATION) += suspend.o swsusp_asm64.o | |
36 | obj-$(CONFIG_AUDIT) += audit.o | 36 | obj-$(CONFIG_AUDIT) += audit.o |
37 | compat-obj-$(CONFIG_AUDIT) += compat_audit.o | 37 | compat-obj-$(CONFIG_AUDIT) += compat_audit.o |
38 | obj-$(CONFIG_COMPAT) += compat_linux.o compat_signal.o \ | 38 | obj-$(CONFIG_COMPAT) += compat_linux.o compat_signal.o \ |
@@ -41,7 +41,7 @@ obj-$(CONFIG_COMPAT) += compat_linux.o compat_signal.o \ | |||
41 | 41 | ||
42 | obj-$(CONFIG_STACKTRACE) += stacktrace.o | 42 | obj-$(CONFIG_STACKTRACE) += stacktrace.o |
43 | obj-$(CONFIG_KPROBES) += kprobes.o | 43 | obj-$(CONFIG_KPROBES) += kprobes.o |
44 | obj-$(CONFIG_FUNCTION_TRACER) += mcount.o | 44 | obj-$(CONFIG_FUNCTION_TRACER) += $(if $(CONFIG_64BIT),mcount64.o,mcount.o) |
45 | obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o | 45 | obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o |
46 | obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o | 46 | obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o |
47 | 47 | ||
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index cae14c499511..bf8b4ae7ff2d 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c | |||
@@ -6,6 +6,9 @@ | |||
6 | * Heiko Carstens <heiko.carstens@de.ibm.com> | 6 | * Heiko Carstens <heiko.carstens@de.ibm.com> |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #define KMSG_COMPONENT "setup" | ||
10 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt | ||
11 | |||
9 | #include <linux/compiler.h> | 12 | #include <linux/compiler.h> |
10 | #include <linux/init.h> | 13 | #include <linux/init.h> |
11 | #include <linux/errno.h> | 14 | #include <linux/errno.h> |
@@ -16,6 +19,7 @@ | |||
16 | #include <linux/module.h> | 19 | #include <linux/module.h> |
17 | #include <linux/pfn.h> | 20 | #include <linux/pfn.h> |
18 | #include <linux/uaccess.h> | 21 | #include <linux/uaccess.h> |
22 | #include <linux/kernel.h> | ||
19 | #include <asm/ebcdic.h> | 23 | #include <asm/ebcdic.h> |
20 | #include <asm/ipl.h> | 24 | #include <asm/ipl.h> |
21 | #include <asm/lowcore.h> | 25 | #include <asm/lowcore.h> |
@@ -35,8 +39,6 @@ | |||
35 | 39 | ||
36 | char kernel_nss_name[NSS_NAME_SIZE + 1]; | 40 | char kernel_nss_name[NSS_NAME_SIZE + 1]; |
37 | 41 | ||
38 | static unsigned long machine_flags; | ||
39 | |||
40 | static void __init setup_boot_command_line(void); | 42 | static void __init setup_boot_command_line(void); |
41 | 43 | ||
42 | /* | 44 | /* |
@@ -81,6 +83,8 @@ asm( | |||
81 | " br 14\n" | 83 | " br 14\n" |
82 | " .size savesys_ipl_nss, .-savesys_ipl_nss\n"); | 84 | " .size savesys_ipl_nss, .-savesys_ipl_nss\n"); |
83 | 85 | ||
86 | static __initdata char upper_command_line[COMMAND_LINE_SIZE]; | ||
87 | |||
84 | static noinline __init void create_kernel_nss(void) | 88 | static noinline __init void create_kernel_nss(void) |
85 | { | 89 | { |
86 | unsigned int i, stext_pfn, eshared_pfn, end_pfn, min_size; | 90 | unsigned int i, stext_pfn, eshared_pfn, end_pfn, min_size; |
@@ -90,7 +94,6 @@ static noinline __init void create_kernel_nss(void) | |||
90 | int response; | 94 | int response; |
91 | size_t len; | 95 | size_t len; |
92 | char *savesys_ptr; | 96 | char *savesys_ptr; |
93 | char upper_command_line[COMMAND_LINE_SIZE]; | ||
94 | char defsys_cmd[DEFSYS_CMD_SIZE]; | 97 | char defsys_cmd[DEFSYS_CMD_SIZE]; |
95 | char savesys_cmd[SAVESYS_CMD_SIZE]; | 98 | char savesys_cmd[SAVESYS_CMD_SIZE]; |
96 | 99 | ||
@@ -141,6 +144,8 @@ static noinline __init void create_kernel_nss(void) | |||
141 | __cpcmd(defsys_cmd, NULL, 0, &response); | 144 | __cpcmd(defsys_cmd, NULL, 0, &response); |
142 | 145 | ||
143 | if (response != 0) { | 146 | if (response != 0) { |
147 | pr_err("Defining the Linux kernel NSS failed with rc=%d\n", | ||
148 | response); | ||
144 | kernel_nss_name[0] = '\0'; | 149 | kernel_nss_name[0] = '\0'; |
145 | return; | 150 | return; |
146 | } | 151 | } |
@@ -153,8 +158,11 @@ static noinline __init void create_kernel_nss(void) | |||
153 | * max SAVESYS_CMD_SIZE | 158 | * max SAVESYS_CMD_SIZE |
154 | * On error: response contains the numeric portion of cp error message. | 159 | * On error: response contains the numeric portion of cp error message. |
155 | * for SAVESYS it will be >= 263 | 160 | * for SAVESYS it will be >= 263 |
161 | * for missing privilege class, it will be 1 | ||
156 | */ | 162 | */ |
157 | if (response > SAVESYS_CMD_SIZE) { | 163 | if (response > SAVESYS_CMD_SIZE || response == 1) { |
164 | pr_err("Saving the Linux kernel NSS failed with rc=%d\n", | ||
165 | response); | ||
158 | kernel_nss_name[0] = '\0'; | 166 | kernel_nss_name[0] = '\0'; |
159 | return; | 167 | return; |
160 | } | 168 | } |
@@ -205,12 +213,9 @@ static noinline __init void detect_machine_type(void) | |||
205 | 213 | ||
206 | /* Running under KVM? If not we assume z/VM */ | 214 | /* Running under KVM? If not we assume z/VM */ |
207 | if (!memcmp(vmms.vm[0].cpi, "\xd2\xe5\xd4", 3)) | 215 | if (!memcmp(vmms.vm[0].cpi, "\xd2\xe5\xd4", 3)) |
208 | machine_flags |= MACHINE_FLAG_KVM; | 216 | S390_lowcore.machine_flags |= MACHINE_FLAG_KVM; |
209 | else | 217 | else |
210 | machine_flags |= MACHINE_FLAG_VM; | 218 | S390_lowcore.machine_flags |= MACHINE_FLAG_VM; |
211 | |||
212 | /* Store machine flags for setting up lowcore early */ | ||
213 | S390_lowcore.machine_flags = machine_flags; | ||
214 | } | 219 | } |
215 | 220 | ||
216 | static __init void early_pgm_check_handler(void) | 221 | static __init void early_pgm_check_handler(void) |
@@ -245,7 +250,7 @@ static noinline __init void setup_hpage(void) | |||
245 | facilities = stfl(); | 250 | facilities = stfl(); |
246 | if (!(facilities & (1UL << 23)) || !(facilities & (1UL << 29))) | 251 | if (!(facilities & (1UL << 23)) || !(facilities & (1UL << 29))) |
247 | return; | 252 | return; |
248 | machine_flags |= MACHINE_FLAG_HPAGE; | 253 | S390_lowcore.machine_flags |= MACHINE_FLAG_HPAGE; |
249 | __ctl_set_bit(0, 23); | 254 | __ctl_set_bit(0, 23); |
250 | #endif | 255 | #endif |
251 | } | 256 | } |
@@ -263,7 +268,7 @@ static __init void detect_mvpg(void) | |||
263 | EX_TABLE(0b,1b) | 268 | EX_TABLE(0b,1b) |
264 | : "=d" (rc) : "0" (-EOPNOTSUPP), "a" (0) : "memory", "cc", "0"); | 269 | : "=d" (rc) : "0" (-EOPNOTSUPP), "a" (0) : "memory", "cc", "0"); |
265 | if (!rc) | 270 | if (!rc) |
266 | machine_flags |= MACHINE_FLAG_MVPG; | 271 | S390_lowcore.machine_flags |= MACHINE_FLAG_MVPG; |
267 | #endif | 272 | #endif |
268 | } | 273 | } |
269 | 274 | ||
@@ -279,7 +284,7 @@ static __init void detect_ieee(void) | |||
279 | EX_TABLE(0b,1b) | 284 | EX_TABLE(0b,1b) |
280 | : "=d" (rc), "=d" (tmp): "0" (-EOPNOTSUPP) : "cc"); | 285 | : "=d" (rc), "=d" (tmp): "0" (-EOPNOTSUPP) : "cc"); |
281 | if (!rc) | 286 | if (!rc) |
282 | machine_flags |= MACHINE_FLAG_IEEE; | 287 | S390_lowcore.machine_flags |= MACHINE_FLAG_IEEE; |
283 | #endif | 288 | #endif |
284 | } | 289 | } |
285 | 290 | ||
@@ -298,7 +303,7 @@ static __init void detect_csp(void) | |||
298 | EX_TABLE(0b,1b) | 303 | EX_TABLE(0b,1b) |
299 | : "=d" (rc) : "0" (-EOPNOTSUPP) : "cc", "0", "1", "2"); | 304 | : "=d" (rc) : "0" (-EOPNOTSUPP) : "cc", "0", "1", "2"); |
300 | if (!rc) | 305 | if (!rc) |
301 | machine_flags |= MACHINE_FLAG_CSP; | 306 | S390_lowcore.machine_flags |= MACHINE_FLAG_CSP; |
302 | #endif | 307 | #endif |
303 | } | 308 | } |
304 | 309 | ||
@@ -315,7 +320,7 @@ static __init void detect_diag9c(void) | |||
315 | EX_TABLE(0b,1b) | 320 | EX_TABLE(0b,1b) |
316 | : "=d" (rc) : "0" (-EOPNOTSUPP), "d" (cpu_address) : "cc"); | 321 | : "=d" (rc) : "0" (-EOPNOTSUPP), "d" (cpu_address) : "cc"); |
317 | if (!rc) | 322 | if (!rc) |
318 | machine_flags |= MACHINE_FLAG_DIAG9C; | 323 | S390_lowcore.machine_flags |= MACHINE_FLAG_DIAG9C; |
319 | } | 324 | } |
320 | 325 | ||
321 | static __init void detect_diag44(void) | 326 | static __init void detect_diag44(void) |
@@ -330,7 +335,7 @@ static __init void detect_diag44(void) | |||
330 | EX_TABLE(0b,1b) | 335 | EX_TABLE(0b,1b) |
331 | : "=d" (rc) : "0" (-EOPNOTSUPP) : "cc"); | 336 | : "=d" (rc) : "0" (-EOPNOTSUPP) : "cc"); |
332 | if (!rc) | 337 | if (!rc) |
333 | machine_flags |= MACHINE_FLAG_DIAG44; | 338 | S390_lowcore.machine_flags |= MACHINE_FLAG_DIAG44; |
334 | #endif | 339 | #endif |
335 | } | 340 | } |
336 | 341 | ||
@@ -341,11 +346,11 @@ static __init void detect_machine_facilities(void) | |||
341 | 346 | ||
342 | facilities = stfl(); | 347 | facilities = stfl(); |
343 | if (facilities & (1 << 28)) | 348 | if (facilities & (1 << 28)) |
344 | machine_flags |= MACHINE_FLAG_IDTE; | 349 | S390_lowcore.machine_flags |= MACHINE_FLAG_IDTE; |
345 | if (facilities & (1 << 23)) | 350 | if (facilities & (1 << 23)) |
346 | machine_flags |= MACHINE_FLAG_PFMF; | 351 | S390_lowcore.machine_flags |= MACHINE_FLAG_PFMF; |
347 | if (facilities & (1 << 4)) | 352 | if (facilities & (1 << 4)) |
348 | machine_flags |= MACHINE_FLAG_MVCOS; | 353 | S390_lowcore.machine_flags |= MACHINE_FLAG_MVCOS; |
349 | #endif | 354 | #endif |
350 | } | 355 | } |
351 | 356 | ||
@@ -367,21 +372,35 @@ static __init void rescue_initrd(void) | |||
367 | } | 372 | } |
368 | 373 | ||
369 | /* Set up boot command line */ | 374 | /* Set up boot command line */ |
370 | static void __init setup_boot_command_line(void) | 375 | static void __init append_to_cmdline(size_t (*ipl_data)(char *, size_t)) |
371 | { | 376 | { |
372 | char *parm = NULL; | 377 | char *parm, *delim; |
378 | size_t rc, len; | ||
379 | |||
380 | len = strlen(boot_command_line); | ||
381 | |||
382 | delim = boot_command_line + len; /* '\0' character position */ | ||
383 | parm = boot_command_line + len + 1; /* append right after '\0' */ | ||
373 | 384 | ||
385 | rc = ipl_data(parm, COMMAND_LINE_SIZE - len - 1); | ||
386 | if (rc) { | ||
387 | if (*parm == '=') | ||
388 | memmove(boot_command_line, parm + 1, rc); | ||
389 | else | ||
390 | *delim = ' '; /* replace '\0' with space */ | ||
391 | } | ||
392 | } | ||
393 | |||
394 | static void __init setup_boot_command_line(void) | ||
395 | { | ||
374 | /* copy arch command line */ | 396 | /* copy arch command line */ |
375 | strlcpy(boot_command_line, COMMAND_LINE, ARCH_COMMAND_LINE_SIZE); | 397 | strlcpy(boot_command_line, COMMAND_LINE, ARCH_COMMAND_LINE_SIZE); |
376 | 398 | ||
377 | /* append IPL PARM data to the boot command line */ | 399 | /* append IPL PARM data to the boot command line */ |
378 | if (MACHINE_IS_VM) { | 400 | if (MACHINE_IS_VM) |
379 | parm = boot_command_line + strlen(boot_command_line); | 401 | append_to_cmdline(append_ipl_vmparm); |
380 | *parm++ = ' '; | 402 | |
381 | get_ipl_vmparm(parm); | 403 | append_to_cmdline(append_ipl_scpdata); |
382 | if (parm[0] == '=') | ||
383 | memmove(boot_command_line, parm + 1, strlen(parm)); | ||
384 | } | ||
385 | } | 404 | } |
386 | 405 | ||
387 | 406 | ||
@@ -413,7 +432,6 @@ void __init startup_init(void) | |||
413 | setup_hpage(); | 432 | setup_hpage(); |
414 | sclp_facilities_detect(); | 433 | sclp_facilities_detect(); |
415 | detect_memory_layout(memory_chunk); | 434 | detect_memory_layout(memory_chunk); |
416 | S390_lowcore.machine_flags = machine_flags; | ||
417 | #ifdef CONFIG_DYNAMIC_FTRACE | 435 | #ifdef CONFIG_DYNAMIC_FTRACE |
418 | S390_lowcore.ftrace_func = (unsigned long)ftrace_caller; | 436 | S390_lowcore.ftrace_func = (unsigned long)ftrace_caller; |
419 | #endif | 437 | #endif |
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index c4c80a22bc1f..f78580a74039 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S | |||
@@ -278,7 +278,8 @@ sysc_return: | |||
278 | bnz BASED(sysc_work) # there is work to do (signals etc.) | 278 | bnz BASED(sysc_work) # there is work to do (signals etc.) |
279 | sysc_restore: | 279 | sysc_restore: |
280 | #ifdef CONFIG_TRACE_IRQFLAGS | 280 | #ifdef CONFIG_TRACE_IRQFLAGS |
281 | la %r1,BASED(sysc_restore_trace_psw) | 281 | la %r1,BASED(sysc_restore_trace_psw_addr) |
282 | l %r1,0(%r1) | ||
282 | lpsw 0(%r1) | 283 | lpsw 0(%r1) |
283 | sysc_restore_trace: | 284 | sysc_restore_trace: |
284 | TRACE_IRQS_CHECK | 285 | TRACE_IRQS_CHECK |
@@ -289,10 +290,15 @@ sysc_leave: | |||
289 | sysc_done: | 290 | sysc_done: |
290 | 291 | ||
291 | #ifdef CONFIG_TRACE_IRQFLAGS | 292 | #ifdef CONFIG_TRACE_IRQFLAGS |
293 | sysc_restore_trace_psw_addr: | ||
294 | .long sysc_restore_trace_psw | ||
295 | |||
296 | .section .data,"aw",@progbits | ||
292 | .align 8 | 297 | .align 8 |
293 | .globl sysc_restore_trace_psw | 298 | .globl sysc_restore_trace_psw |
294 | sysc_restore_trace_psw: | 299 | sysc_restore_trace_psw: |
295 | .long 0, sysc_restore_trace + 0x80000000 | 300 | .long 0, sysc_restore_trace + 0x80000000 |
301 | .previous | ||
296 | #endif | 302 | #endif |
297 | 303 | ||
298 | # | 304 | # |
@@ -606,7 +612,8 @@ io_return: | |||
606 | bnz BASED(io_work) # there is work to do (signals etc.) | 612 | bnz BASED(io_work) # there is work to do (signals etc.) |
607 | io_restore: | 613 | io_restore: |
608 | #ifdef CONFIG_TRACE_IRQFLAGS | 614 | #ifdef CONFIG_TRACE_IRQFLAGS |
609 | la %r1,BASED(io_restore_trace_psw) | 615 | la %r1,BASED(io_restore_trace_psw_addr) |
616 | l %r1,0(%r1) | ||
610 | lpsw 0(%r1) | 617 | lpsw 0(%r1) |
611 | io_restore_trace: | 618 | io_restore_trace: |
612 | TRACE_IRQS_CHECK | 619 | TRACE_IRQS_CHECK |
@@ -617,10 +624,15 @@ io_leave: | |||
617 | io_done: | 624 | io_done: |
618 | 625 | ||
619 | #ifdef CONFIG_TRACE_IRQFLAGS | 626 | #ifdef CONFIG_TRACE_IRQFLAGS |
627 | io_restore_trace_psw_addr: | ||
628 | .long io_restore_trace_psw | ||
629 | |||
630 | .section .data,"aw",@progbits | ||
620 | .align 8 | 631 | .align 8 |
621 | .globl io_restore_trace_psw | 632 | .globl io_restore_trace_psw |
622 | io_restore_trace_psw: | 633 | io_restore_trace_psw: |
623 | .long 0, io_restore_trace + 0x80000000 | 634 | .long 0, io_restore_trace + 0x80000000 |
635 | .previous | ||
624 | #endif | 636 | #endif |
625 | 637 | ||
626 | # | 638 | # |
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index f6618e9e15ef..009ca6175db9 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S | |||
@@ -284,10 +284,12 @@ sysc_leave: | |||
284 | sysc_done: | 284 | sysc_done: |
285 | 285 | ||
286 | #ifdef CONFIG_TRACE_IRQFLAGS | 286 | #ifdef CONFIG_TRACE_IRQFLAGS |
287 | .section .data,"aw",@progbits | ||
287 | .align 8 | 288 | .align 8 |
288 | .globl sysc_restore_trace_psw | 289 | .globl sysc_restore_trace_psw |
289 | sysc_restore_trace_psw: | 290 | sysc_restore_trace_psw: |
290 | .quad 0, sysc_restore_trace | 291 | .quad 0, sysc_restore_trace |
292 | .previous | ||
291 | #endif | 293 | #endif |
292 | 294 | ||
293 | # | 295 | # |
@@ -595,10 +597,12 @@ io_leave: | |||
595 | io_done: | 597 | io_done: |
596 | 598 | ||
597 | #ifdef CONFIG_TRACE_IRQFLAGS | 599 | #ifdef CONFIG_TRACE_IRQFLAGS |
600 | .section .data,"aw",@progbits | ||
598 | .align 8 | 601 | .align 8 |
599 | .globl io_restore_trace_psw | 602 | .globl io_restore_trace_psw |
600 | io_restore_trace_psw: | 603 | io_restore_trace_psw: |
601 | .quad 0, io_restore_trace | 604 | .quad 0, io_restore_trace |
605 | .previous | ||
602 | #endif | 606 | #endif |
603 | 607 | ||
604 | # | 608 | # |
diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S index ec6882348520..c52b4f7742fa 100644 --- a/arch/s390/kernel/head.S +++ b/arch/s390/kernel/head.S | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <asm/asm-offsets.h> | 27 | #include <asm/asm-offsets.h> |
28 | #include <asm/thread_info.h> | 28 | #include <asm/thread_info.h> |
29 | #include <asm/page.h> | 29 | #include <asm/page.h> |
30 | #include <asm/cpu.h> | ||
30 | 31 | ||
31 | #ifdef CONFIG_64BIT | 32 | #ifdef CONFIG_64BIT |
32 | #define ARCH_OFFSET 4 | 33 | #define ARCH_OFFSET 4 |
diff --git a/arch/s390/kernel/head31.S b/arch/s390/kernel/head31.S index 2ced846065b7..602b508cd4c4 100644 --- a/arch/s390/kernel/head31.S +++ b/arch/s390/kernel/head31.S | |||
@@ -24,6 +24,7 @@ startup_continue: | |||
24 | # Setup stack | 24 | # Setup stack |
25 | # | 25 | # |
26 | l %r15,.Linittu-.LPG1(%r13) | 26 | l %r15,.Linittu-.LPG1(%r13) |
27 | st %r15,__LC_THREAD_INFO # cache thread info in lowcore | ||
27 | mvc __LC_CURRENT(4),__TI_task(%r15) | 28 | mvc __LC_CURRENT(4),__TI_task(%r15) |
28 | ahi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union+THREAD_SIZE | 29 | ahi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union+THREAD_SIZE |
29 | st %r15,__LC_KERNEL_STACK # set end of kernel stack | 30 | st %r15,__LC_KERNEL_STACK # set end of kernel stack |
diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S index 65667b2e65ce..6a250808092b 100644 --- a/arch/s390/kernel/head64.S +++ b/arch/s390/kernel/head64.S | |||
@@ -62,9 +62,9 @@ startup_continue: | |||
62 | clr %r11,%r12 | 62 | clr %r11,%r12 |
63 | je 5f # no more space in prefix array | 63 | je 5f # no more space in prefix array |
64 | 4: | 64 | 4: |
65 | ahi %r8,1 # next cpu (r8 += 1) | 65 | ahi %r8,1 # next cpu (r8 += 1) |
66 | cl %r8,.Llast_cpu-.LPG1(%r13) # is last possible cpu ? | 66 | chi %r8,MAX_CPU_ADDRESS # is last possible cpu ? |
67 | jl 1b # jump if not last cpu | 67 | jle 1b # jump if not last cpu |
68 | 5: | 68 | 5: |
69 | lhi %r1,2 # mode 2 = esame (dump) | 69 | lhi %r1,2 # mode 2 = esame (dump) |
70 | j 6f | 70 | j 6f |
@@ -92,6 +92,7 @@ startup_continue: | |||
92 | # Setup stack | 92 | # Setup stack |
93 | # | 93 | # |
94 | larl %r15,init_thread_union | 94 | larl %r15,init_thread_union |
95 | stg %r15,__LC_THREAD_INFO # cache thread info in lowcore | ||
95 | lg %r14,__TI_task(%r15) # cache current in lowcore | 96 | lg %r14,__TI_task(%r15) # cache current in lowcore |
96 | stg %r14,__LC_CURRENT | 97 | stg %r14,__LC_CURRENT |
97 | aghi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union + THREAD_SIZE | 98 | aghi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union + THREAD_SIZE |
@@ -129,8 +130,6 @@ startup_continue: | |||
129 | #ifdef CONFIG_ZFCPDUMP | 130 | #ifdef CONFIG_ZFCPDUMP |
130 | .Lcurrent_cpu: | 131 | .Lcurrent_cpu: |
131 | .long 0x0 | 132 | .long 0x0 |
132 | .Llast_cpu: | ||
133 | .long 0x0000ffff | ||
134 | .Lpref_arr_ptr: | 133 | .Lpref_arr_ptr: |
135 | .long zfcpdump_prefix_array | 134 | .long zfcpdump_prefix_array |
136 | #endif /* CONFIG_ZFCPDUMP */ | 135 | #endif /* CONFIG_ZFCPDUMP */ |
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index 371a2d88f4ac..ee57a42e6e93 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c | |||
@@ -272,17 +272,18 @@ static ssize_t ipl_type_show(struct kobject *kobj, struct kobj_attribute *attr, | |||
272 | static struct kobj_attribute sys_ipl_type_attr = __ATTR_RO(ipl_type); | 272 | static struct kobj_attribute sys_ipl_type_attr = __ATTR_RO(ipl_type); |
273 | 273 | ||
274 | /* VM IPL PARM routines */ | 274 | /* VM IPL PARM routines */ |
275 | static void reipl_get_ascii_vmparm(char *dest, | 275 | size_t reipl_get_ascii_vmparm(char *dest, size_t size, |
276 | const struct ipl_parameter_block *ipb) | 276 | const struct ipl_parameter_block *ipb) |
277 | { | 277 | { |
278 | int i; | 278 | int i; |
279 | int len = 0; | 279 | size_t len; |
280 | char has_lowercase = 0; | 280 | char has_lowercase = 0; |
281 | 281 | ||
282 | len = 0; | ||
282 | if ((ipb->ipl_info.ccw.vm_flags & DIAG308_VM_FLAGS_VP_VALID) && | 283 | if ((ipb->ipl_info.ccw.vm_flags & DIAG308_VM_FLAGS_VP_VALID) && |
283 | (ipb->ipl_info.ccw.vm_parm_len > 0)) { | 284 | (ipb->ipl_info.ccw.vm_parm_len > 0)) { |
284 | 285 | ||
285 | len = ipb->ipl_info.ccw.vm_parm_len; | 286 | len = min_t(size_t, size - 1, ipb->ipl_info.ccw.vm_parm_len); |
286 | memcpy(dest, ipb->ipl_info.ccw.vm_parm, len); | 287 | memcpy(dest, ipb->ipl_info.ccw.vm_parm, len); |
287 | /* If at least one character is lowercase, we assume mixed | 288 | /* If at least one character is lowercase, we assume mixed |
288 | * case; otherwise we convert everything to lowercase. | 289 | * case; otherwise we convert everything to lowercase. |
@@ -299,14 +300,20 @@ static void reipl_get_ascii_vmparm(char *dest, | |||
299 | EBCASC(dest, len); | 300 | EBCASC(dest, len); |
300 | } | 301 | } |
301 | dest[len] = 0; | 302 | dest[len] = 0; |
303 | |||
304 | return len; | ||
302 | } | 305 | } |
303 | 306 | ||
304 | void get_ipl_vmparm(char *dest) | 307 | size_t append_ipl_vmparm(char *dest, size_t size) |
305 | { | 308 | { |
309 | size_t rc; | ||
310 | |||
311 | rc = 0; | ||
306 | if (diag308_set_works && (ipl_block.hdr.pbt == DIAG308_IPL_TYPE_CCW)) | 312 | if (diag308_set_works && (ipl_block.hdr.pbt == DIAG308_IPL_TYPE_CCW)) |
307 | reipl_get_ascii_vmparm(dest, &ipl_block); | 313 | rc = reipl_get_ascii_vmparm(dest, size, &ipl_block); |
308 | else | 314 | else |
309 | dest[0] = 0; | 315 | dest[0] = 0; |
316 | return rc; | ||
310 | } | 317 | } |
311 | 318 | ||
312 | static ssize_t ipl_vm_parm_show(struct kobject *kobj, | 319 | static ssize_t ipl_vm_parm_show(struct kobject *kobj, |
@@ -314,10 +321,65 @@ static ssize_t ipl_vm_parm_show(struct kobject *kobj, | |||
314 | { | 321 | { |
315 | char parm[DIAG308_VMPARM_SIZE + 1] = {}; | 322 | char parm[DIAG308_VMPARM_SIZE + 1] = {}; |
316 | 323 | ||
317 | get_ipl_vmparm(parm); | 324 | append_ipl_vmparm(parm, sizeof(parm)); |
318 | return sprintf(page, "%s\n", parm); | 325 | return sprintf(page, "%s\n", parm); |
319 | } | 326 | } |
320 | 327 | ||
328 | static size_t scpdata_length(const char* buf, size_t count) | ||
329 | { | ||
330 | while (count) { | ||
331 | if (buf[count - 1] != '\0' && buf[count - 1] != ' ') | ||
332 | break; | ||
333 | count--; | ||
334 | } | ||
335 | return count; | ||
336 | } | ||
337 | |||
338 | size_t reipl_append_ascii_scpdata(char *dest, size_t size, | ||
339 | const struct ipl_parameter_block *ipb) | ||
340 | { | ||
341 | size_t count; | ||
342 | size_t i; | ||
343 | int has_lowercase; | ||
344 | |||
345 | count = min(size - 1, scpdata_length(ipb->ipl_info.fcp.scp_data, | ||
346 | ipb->ipl_info.fcp.scp_data_len)); | ||
347 | if (!count) | ||
348 | goto out; | ||
349 | |||
350 | has_lowercase = 0; | ||
351 | for (i = 0; i < count; i++) { | ||
352 | if (!isascii(ipb->ipl_info.fcp.scp_data[i])) { | ||
353 | count = 0; | ||
354 | goto out; | ||
355 | } | ||
356 | if (!has_lowercase && islower(ipb->ipl_info.fcp.scp_data[i])) | ||
357 | has_lowercase = 1; | ||
358 | } | ||
359 | |||
360 | if (has_lowercase) | ||
361 | memcpy(dest, ipb->ipl_info.fcp.scp_data, count); | ||
362 | else | ||
363 | for (i = 0; i < count; i++) | ||
364 | dest[i] = tolower(ipb->ipl_info.fcp.scp_data[i]); | ||
365 | out: | ||
366 | dest[count] = '\0'; | ||
367 | return count; | ||
368 | } | ||
369 | |||
370 | size_t append_ipl_scpdata(char *dest, size_t len) | ||
371 | { | ||
372 | size_t rc; | ||
373 | |||
374 | rc = 0; | ||
375 | if (ipl_block.hdr.pbt == DIAG308_IPL_TYPE_FCP) | ||
376 | rc = reipl_append_ascii_scpdata(dest, len, &ipl_block); | ||
377 | else | ||
378 | dest[0] = 0; | ||
379 | return rc; | ||
380 | } | ||
381 | |||
382 | |||
321 | static struct kobj_attribute sys_ipl_vm_parm_attr = | 383 | static struct kobj_attribute sys_ipl_vm_parm_attr = |
322 | __ATTR(parm, S_IRUGO, ipl_vm_parm_show, NULL); | 384 | __ATTR(parm, S_IRUGO, ipl_vm_parm_show, NULL); |
323 | 385 | ||
@@ -553,7 +615,7 @@ static ssize_t reipl_generic_vmparm_show(struct ipl_parameter_block *ipb, | |||
553 | { | 615 | { |
554 | char vmparm[DIAG308_VMPARM_SIZE + 1] = {}; | 616 | char vmparm[DIAG308_VMPARM_SIZE + 1] = {}; |
555 | 617 | ||
556 | reipl_get_ascii_vmparm(vmparm, ipb); | 618 | reipl_get_ascii_vmparm(vmparm, sizeof(vmparm), ipb); |
557 | return sprintf(page, "%s\n", vmparm); | 619 | return sprintf(page, "%s\n", vmparm); |
558 | } | 620 | } |
559 | 621 | ||
@@ -626,6 +688,59 @@ static struct kobj_attribute sys_reipl_ccw_vmparm_attr = | |||
626 | 688 | ||
627 | /* FCP reipl device attributes */ | 689 | /* FCP reipl device attributes */ |
628 | 690 | ||
691 | static ssize_t reipl_fcp_scpdata_read(struct kobject *kobj, | ||
692 | struct bin_attribute *attr, | ||
693 | char *buf, loff_t off, size_t count) | ||
694 | { | ||
695 | size_t size = reipl_block_fcp->ipl_info.fcp.scp_data_len; | ||
696 | void *scp_data = reipl_block_fcp->ipl_info.fcp.scp_data; | ||
697 | |||
698 | return memory_read_from_buffer(buf, count, &off, scp_data, size); | ||
699 | } | ||
700 | |||
701 | static ssize_t reipl_fcp_scpdata_write(struct kobject *kobj, | ||
702 | struct bin_attribute *attr, | ||
703 | char *buf, loff_t off, size_t count) | ||
704 | { | ||
705 | size_t padding; | ||
706 | size_t scpdata_len; | ||
707 | |||
708 | if (off < 0) | ||
709 | return -EINVAL; | ||
710 | |||
711 | if (off >= DIAG308_SCPDATA_SIZE) | ||
712 | return -ENOSPC; | ||
713 | |||
714 | if (count > DIAG308_SCPDATA_SIZE - off) | ||
715 | count = DIAG308_SCPDATA_SIZE - off; | ||
716 | |||
717 | memcpy(reipl_block_fcp->ipl_info.fcp.scp_data, buf + off, count); | ||
718 | scpdata_len = off + count; | ||
719 | |||
720 | if (scpdata_len % 8) { | ||
721 | padding = 8 - (scpdata_len % 8); | ||
722 | memset(reipl_block_fcp->ipl_info.fcp.scp_data + scpdata_len, | ||
723 | 0, padding); | ||
724 | scpdata_len += padding; | ||
725 | } | ||
726 | |||
727 | reipl_block_fcp->ipl_info.fcp.scp_data_len = scpdata_len; | ||
728 | reipl_block_fcp->hdr.len = IPL_PARM_BLK_FCP_LEN + scpdata_len; | ||
729 | reipl_block_fcp->hdr.blk0_len = IPL_PARM_BLK0_FCP_LEN + scpdata_len; | ||
730 | |||
731 | return count; | ||
732 | } | ||
733 | |||
734 | static struct bin_attribute sys_reipl_fcp_scp_data_attr = { | ||
735 | .attr = { | ||
736 | .name = "scp_data", | ||
737 | .mode = S_IRUGO | S_IWUSR, | ||
738 | }, | ||
739 | .size = PAGE_SIZE, | ||
740 | .read = reipl_fcp_scpdata_read, | ||
741 | .write = reipl_fcp_scpdata_write, | ||
742 | }; | ||
743 | |||
629 | DEFINE_IPL_ATTR_RW(reipl_fcp, wwpn, "0x%016llx\n", "%016llx\n", | 744 | DEFINE_IPL_ATTR_RW(reipl_fcp, wwpn, "0x%016llx\n", "%016llx\n", |
630 | reipl_block_fcp->ipl_info.fcp.wwpn); | 745 | reipl_block_fcp->ipl_info.fcp.wwpn); |
631 | DEFINE_IPL_ATTR_RW(reipl_fcp, lun, "0x%016llx\n", "%016llx\n", | 746 | DEFINE_IPL_ATTR_RW(reipl_fcp, lun, "0x%016llx\n", "%016llx\n", |
@@ -647,7 +762,6 @@ static struct attribute *reipl_fcp_attrs[] = { | |||
647 | }; | 762 | }; |
648 | 763 | ||
649 | static struct attribute_group reipl_fcp_attr_group = { | 764 | static struct attribute_group reipl_fcp_attr_group = { |
650 | .name = IPL_FCP_STR, | ||
651 | .attrs = reipl_fcp_attrs, | 765 | .attrs = reipl_fcp_attrs, |
652 | }; | 766 | }; |
653 | 767 | ||
@@ -895,6 +1009,7 @@ static struct kobj_attribute reipl_type_attr = | |||
895 | __ATTR(reipl_type, 0644, reipl_type_show, reipl_type_store); | 1009 | __ATTR(reipl_type, 0644, reipl_type_show, reipl_type_store); |
896 | 1010 | ||
897 | static struct kset *reipl_kset; | 1011 | static struct kset *reipl_kset; |
1012 | static struct kset *reipl_fcp_kset; | ||
898 | 1013 | ||
899 | static void get_ipl_string(char *dst, struct ipl_parameter_block *ipb, | 1014 | static void get_ipl_string(char *dst, struct ipl_parameter_block *ipb, |
900 | const enum ipl_method m) | 1015 | const enum ipl_method m) |
@@ -906,7 +1021,7 @@ static void get_ipl_string(char *dst, struct ipl_parameter_block *ipb, | |||
906 | 1021 | ||
907 | reipl_get_ascii_loadparm(loadparm, ipb); | 1022 | reipl_get_ascii_loadparm(loadparm, ipb); |
908 | reipl_get_ascii_nss_name(nss_name, ipb); | 1023 | reipl_get_ascii_nss_name(nss_name, ipb); |
909 | reipl_get_ascii_vmparm(vmparm, ipb); | 1024 | reipl_get_ascii_vmparm(vmparm, sizeof(vmparm), ipb); |
910 | 1025 | ||
911 | switch (m) { | 1026 | switch (m) { |
912 | case REIPL_METHOD_CCW_VM: | 1027 | case REIPL_METHOD_CCW_VM: |
@@ -1076,23 +1191,44 @@ static int __init reipl_fcp_init(void) | |||
1076 | int rc; | 1191 | int rc; |
1077 | 1192 | ||
1078 | if (!diag308_set_works) { | 1193 | if (!diag308_set_works) { |
1079 | if (ipl_info.type == IPL_TYPE_FCP) | 1194 | if (ipl_info.type == IPL_TYPE_FCP) { |
1080 | make_attrs_ro(reipl_fcp_attrs); | 1195 | make_attrs_ro(reipl_fcp_attrs); |
1081 | else | 1196 | sys_reipl_fcp_scp_data_attr.attr.mode = S_IRUGO; |
1197 | } else | ||
1082 | return 0; | 1198 | return 0; |
1083 | } | 1199 | } |
1084 | 1200 | ||
1085 | reipl_block_fcp = (void *) get_zeroed_page(GFP_KERNEL); | 1201 | reipl_block_fcp = (void *) get_zeroed_page(GFP_KERNEL); |
1086 | if (!reipl_block_fcp) | 1202 | if (!reipl_block_fcp) |
1087 | return -ENOMEM; | 1203 | return -ENOMEM; |
1088 | rc = sysfs_create_group(&reipl_kset->kobj, &reipl_fcp_attr_group); | 1204 | |
1205 | /* sysfs: create fcp kset for mixing attr group and bin attrs */ | ||
1206 | reipl_fcp_kset = kset_create_and_add(IPL_FCP_STR, NULL, | ||
1207 | &reipl_kset->kobj); | ||
1208 | if (!reipl_kset) { | ||
1209 | free_page((unsigned long) reipl_block_fcp); | ||
1210 | return -ENOMEM; | ||
1211 | } | ||
1212 | |||
1213 | rc = sysfs_create_group(&reipl_fcp_kset->kobj, &reipl_fcp_attr_group); | ||
1214 | if (rc) { | ||
1215 | kset_unregister(reipl_fcp_kset); | ||
1216 | free_page((unsigned long) reipl_block_fcp); | ||
1217 | return rc; | ||
1218 | } | ||
1219 | |||
1220 | rc = sysfs_create_bin_file(&reipl_fcp_kset->kobj, | ||
1221 | &sys_reipl_fcp_scp_data_attr); | ||
1089 | if (rc) { | 1222 | if (rc) { |
1090 | free_page((unsigned long)reipl_block_fcp); | 1223 | sysfs_remove_group(&reipl_fcp_kset->kobj, &reipl_fcp_attr_group); |
1224 | kset_unregister(reipl_fcp_kset); | ||
1225 | free_page((unsigned long) reipl_block_fcp); | ||
1091 | return rc; | 1226 | return rc; |
1092 | } | 1227 | } |
1093 | if (ipl_info.type == IPL_TYPE_FCP) { | 1228 | |
1229 | if (ipl_info.type == IPL_TYPE_FCP) | ||
1094 | memcpy(reipl_block_fcp, IPL_PARMBLOCK_START, PAGE_SIZE); | 1230 | memcpy(reipl_block_fcp, IPL_PARMBLOCK_START, PAGE_SIZE); |
1095 | } else { | 1231 | else { |
1096 | reipl_block_fcp->hdr.len = IPL_PARM_BLK_FCP_LEN; | 1232 | reipl_block_fcp->hdr.len = IPL_PARM_BLK_FCP_LEN; |
1097 | reipl_block_fcp->hdr.version = IPL_PARM_BLOCK_VERSION; | 1233 | reipl_block_fcp->hdr.version = IPL_PARM_BLOCK_VERSION; |
1098 | reipl_block_fcp->hdr.blk0_len = IPL_PARM_BLK0_FCP_LEN; | 1234 | reipl_block_fcp->hdr.blk0_len = IPL_PARM_BLK0_FCP_LEN; |
diff --git a/arch/s390/kernel/mcount.S b/arch/s390/kernel/mcount.S index 2a0a5e97ba8c..dfe015d7398c 100644 --- a/arch/s390/kernel/mcount.S +++ b/arch/s390/kernel/mcount.S | |||
@@ -11,111 +11,27 @@ | |||
11 | ftrace_stub: | 11 | ftrace_stub: |
12 | br %r14 | 12 | br %r14 |
13 | 13 | ||
14 | #ifdef CONFIG_64BIT | ||
15 | |||
16 | #ifdef CONFIG_DYNAMIC_FTRACE | ||
17 | |||
18 | .globl _mcount | 14 | .globl _mcount |
19 | _mcount: | 15 | _mcount: |
20 | br %r14 | 16 | #ifdef CONFIG_DYNAMIC_FTRACE |
21 | |||
22 | .globl ftrace_caller | ||
23 | ftrace_caller: | ||
24 | larl %r1,function_trace_stop | ||
25 | icm %r1,0xf,0(%r1) | ||
26 | bnzr %r14 | ||
27 | stmg %r2,%r5,32(%r15) | ||
28 | stg %r14,112(%r15) | ||
29 | lgr %r1,%r15 | ||
30 | aghi %r15,-160 | ||
31 | stg %r1,__SF_BACKCHAIN(%r15) | ||
32 | lgr %r2,%r14 | ||
33 | lg %r3,168(%r15) | ||
34 | larl %r14,ftrace_dyn_func | ||
35 | lg %r14,0(%r14) | ||
36 | basr %r14,%r14 | ||
37 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
38 | .globl ftrace_graph_caller | ||
39 | ftrace_graph_caller: | ||
40 | # This unconditional branch gets runtime patched. Change only if | ||
41 | # you know what you are doing. See ftrace_enable_graph_caller(). | ||
42 | j 0f | ||
43 | lg %r2,272(%r15) | ||
44 | lg %r3,168(%r15) | ||
45 | brasl %r14,prepare_ftrace_return | ||
46 | stg %r2,168(%r15) | ||
47 | 0: | ||
48 | #endif | ||
49 | aghi %r15,160 | ||
50 | lmg %r2,%r5,32(%r15) | ||
51 | lg %r14,112(%r15) | ||
52 | br %r14 | 17 | br %r14 |
53 | 18 | ||
54 | .data | 19 | .data |
55 | .globl ftrace_dyn_func | 20 | .globl ftrace_dyn_func |
56 | ftrace_dyn_func: | 21 | ftrace_dyn_func: |
57 | .quad ftrace_stub | 22 | .long ftrace_stub |
58 | .previous | 23 | .previous |
59 | 24 | ||
60 | #else /* CONFIG_DYNAMIC_FTRACE */ | ||
61 | |||
62 | .globl _mcount | ||
63 | _mcount: | ||
64 | larl %r1,function_trace_stop | ||
65 | icm %r1,0xf,0(%r1) | ||
66 | bnzr %r14 | ||
67 | stmg %r2,%r5,32(%r15) | ||
68 | stg %r14,112(%r15) | ||
69 | lgr %r1,%r15 | ||
70 | aghi %r15,-160 | ||
71 | stg %r1,__SF_BACKCHAIN(%r15) | ||
72 | lgr %r2,%r14 | ||
73 | lg %r3,168(%r15) | ||
74 | larl %r14,ftrace_trace_function | ||
75 | lg %r14,0(%r14) | ||
76 | basr %r14,%r14 | ||
77 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
78 | lg %r2,272(%r15) | ||
79 | lg %r3,168(%r15) | ||
80 | brasl %r14,prepare_ftrace_return | ||
81 | stg %r2,168(%r15) | ||
82 | #endif | ||
83 | aghi %r15,160 | ||
84 | lmg %r2,%r5,32(%r15) | ||
85 | lg %r14,112(%r15) | ||
86 | br %r14 | ||
87 | |||
88 | #endif /* CONFIG_DYNAMIC_FTRACE */ | ||
89 | |||
90 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
91 | |||
92 | .globl return_to_handler | ||
93 | return_to_handler: | ||
94 | stmg %r2,%r5,32(%r15) | ||
95 | lgr %r1,%r15 | ||
96 | aghi %r15,-160 | ||
97 | stg %r1,__SF_BACKCHAIN(%r15) | ||
98 | brasl %r14,ftrace_return_to_handler | ||
99 | aghi %r15,160 | ||
100 | lgr %r14,%r2 | ||
101 | lmg %r2,%r5,32(%r15) | ||
102 | br %r14 | ||
103 | |||
104 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ | ||
105 | |||
106 | #else /* CONFIG_64BIT */ | ||
107 | |||
108 | #ifdef CONFIG_DYNAMIC_FTRACE | ||
109 | |||
110 | .globl _mcount | ||
111 | _mcount: | ||
112 | br %r14 | ||
113 | |||
114 | .globl ftrace_caller | 25 | .globl ftrace_caller |
115 | ftrace_caller: | 26 | ftrace_caller: |
27 | #endif | ||
116 | stm %r2,%r5,16(%r15) | 28 | stm %r2,%r5,16(%r15) |
117 | bras %r1,2f | 29 | bras %r1,2f |
30 | #ifdef CONFIG_DYNAMIC_FTRACE | ||
31 | 0: .long ftrace_dyn_func | ||
32 | #else | ||
118 | 0: .long ftrace_trace_function | 33 | 0: .long ftrace_trace_function |
34 | #endif | ||
119 | 1: .long function_trace_stop | 35 | 1: .long function_trace_stop |
120 | 2: l %r2,1b-0b(%r1) | 36 | 2: l %r2,1b-0b(%r1) |
121 | icm %r2,0xf,0(%r2) | 37 | icm %r2,0xf,0(%r2) |
@@ -131,53 +47,13 @@ ftrace_caller: | |||
131 | l %r14,0(%r14) | 47 | l %r14,0(%r14) |
132 | basr %r14,%r14 | 48 | basr %r14,%r14 |
133 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 49 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
50 | #ifdef CONFIG_DYNAMIC_FTRACE | ||
134 | .globl ftrace_graph_caller | 51 | .globl ftrace_graph_caller |
135 | ftrace_graph_caller: | 52 | ftrace_graph_caller: |
136 | # This unconditional branch gets runtime patched. Change only if | 53 | # This unconditional branch gets runtime patched. Change only if |
137 | # you know what you are doing. See ftrace_enable_graph_caller(). | 54 | # you know what you are doing. See ftrace_enable_graph_caller(). |
138 | j 1f | 55 | j 1f |
139 | bras %r1,0f | ||
140 | .long prepare_ftrace_return | ||
141 | 0: l %r2,152(%r15) | ||
142 | l %r4,0(%r1) | ||
143 | l %r3,100(%r15) | ||
144 | basr %r14,%r4 | ||
145 | st %r2,100(%r15) | ||
146 | 1: | ||
147 | #endif | 56 | #endif |
148 | ahi %r15,96 | ||
149 | l %r14,56(%r15) | ||
150 | 3: lm %r2,%r5,16(%r15) | ||
151 | br %r14 | ||
152 | |||
153 | .data | ||
154 | .globl ftrace_dyn_func | ||
155 | ftrace_dyn_func: | ||
156 | .long ftrace_stub | ||
157 | .previous | ||
158 | |||
159 | #else /* CONFIG_DYNAMIC_FTRACE */ | ||
160 | |||
161 | .globl _mcount | ||
162 | _mcount: | ||
163 | stm %r2,%r5,16(%r15) | ||
164 | bras %r1,2f | ||
165 | 0: .long ftrace_trace_function | ||
166 | 1: .long function_trace_stop | ||
167 | 2: l %r2,1b-0b(%r1) | ||
168 | icm %r2,0xf,0(%r2) | ||
169 | jnz 3f | ||
170 | st %r14,56(%r15) | ||
171 | lr %r0,%r15 | ||
172 | ahi %r15,-96 | ||
173 | l %r3,100(%r15) | ||
174 | la %r2,0(%r14) | ||
175 | st %r0,__SF_BACKCHAIN(%r15) | ||
176 | la %r3,0(%r3) | ||
177 | l %r14,0b-0b(%r1) | ||
178 | l %r14,0(%r14) | ||
179 | basr %r14,%r14 | ||
180 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
181 | bras %r1,0f | 57 | bras %r1,0f |
182 | .long prepare_ftrace_return | 58 | .long prepare_ftrace_return |
183 | 0: l %r2,152(%r15) | 59 | 0: l %r2,152(%r15) |
@@ -185,14 +61,13 @@ _mcount: | |||
185 | l %r3,100(%r15) | 61 | l %r3,100(%r15) |
186 | basr %r14,%r4 | 62 | basr %r14,%r4 |
187 | st %r2,100(%r15) | 63 | st %r2,100(%r15) |
64 | 1: | ||
188 | #endif | 65 | #endif |
189 | ahi %r15,96 | 66 | ahi %r15,96 |
190 | l %r14,56(%r15) | 67 | l %r14,56(%r15) |
191 | 3: lm %r2,%r5,16(%r15) | 68 | 3: lm %r2,%r5,16(%r15) |
192 | br %r14 | 69 | br %r14 |
193 | 70 | ||
194 | #endif /* CONFIG_DYNAMIC_FTRACE */ | ||
195 | |||
196 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 71 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
197 | 72 | ||
198 | .globl return_to_handler | 73 | .globl return_to_handler |
@@ -211,6 +86,4 @@ return_to_handler: | |||
211 | lm %r2,%r5,16(%r15) | 86 | lm %r2,%r5,16(%r15) |
212 | br %r14 | 87 | br %r14 |
213 | 88 | ||
214 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ | 89 | #endif |
215 | |||
216 | #endif /* CONFIG_64BIT */ | ||
diff --git a/arch/s390/kernel/mcount64.S b/arch/s390/kernel/mcount64.S new file mode 100644 index 000000000000..c37211c6092b --- /dev/null +++ b/arch/s390/kernel/mcount64.S | |||
@@ -0,0 +1,78 @@ | |||
1 | /* | ||
2 | * Copyright IBM Corp. 2008,2009 | ||
3 | * | ||
4 | * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>, | ||
5 | * | ||
6 | */ | ||
7 | |||
8 | #include <asm/asm-offsets.h> | ||
9 | |||
10 | .globl ftrace_stub | ||
11 | ftrace_stub: | ||
12 | br %r14 | ||
13 | |||
14 | .globl _mcount | ||
15 | _mcount: | ||
16 | #ifdef CONFIG_DYNAMIC_FTRACE | ||
17 | br %r14 | ||
18 | |||
19 | .data | ||
20 | .globl ftrace_dyn_func | ||
21 | ftrace_dyn_func: | ||
22 | .quad ftrace_stub | ||
23 | .previous | ||
24 | |||
25 | .globl ftrace_caller | ||
26 | ftrace_caller: | ||
27 | #endif | ||
28 | larl %r1,function_trace_stop | ||
29 | icm %r1,0xf,0(%r1) | ||
30 | bnzr %r14 | ||
31 | stmg %r2,%r5,32(%r15) | ||
32 | stg %r14,112(%r15) | ||
33 | lgr %r1,%r15 | ||
34 | aghi %r15,-160 | ||
35 | stg %r1,__SF_BACKCHAIN(%r15) | ||
36 | lgr %r2,%r14 | ||
37 | lg %r3,168(%r15) | ||
38 | #ifdef CONFIG_DYNAMIC_FTRACE | ||
39 | larl %r14,ftrace_dyn_func | ||
40 | #else | ||
41 | larl %r14,ftrace_trace_function | ||
42 | #endif | ||
43 | lg %r14,0(%r14) | ||
44 | basr %r14,%r14 | ||
45 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
46 | #ifdef CONFIG_DYNAMIC_FTRACE | ||
47 | .globl ftrace_graph_caller | ||
48 | ftrace_graph_caller: | ||
49 | # This unconditional branch gets runtime patched. Change only if | ||
50 | # you know what you are doing. See ftrace_enable_graph_caller(). | ||
51 | j 0f | ||
52 | #endif | ||
53 | lg %r2,272(%r15) | ||
54 | lg %r3,168(%r15) | ||
55 | brasl %r14,prepare_ftrace_return | ||
56 | stg %r2,168(%r15) | ||
57 | 0: | ||
58 | #endif | ||
59 | aghi %r15,160 | ||
60 | lmg %r2,%r5,32(%r15) | ||
61 | lg %r14,112(%r15) | ||
62 | br %r14 | ||
63 | |||
64 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
65 | |||
66 | .globl return_to_handler | ||
67 | return_to_handler: | ||
68 | stmg %r2,%r5,32(%r15) | ||
69 | lgr %r1,%r15 | ||
70 | aghi %r15,-160 | ||
71 | stg %r1,__SF_BACKCHAIN(%r15) | ||
72 | brasl %r14,ftrace_return_to_handler | ||
73 | aghi %r15,160 | ||
74 | lgr %r14,%r2 | ||
75 | lmg %r2,%r5,32(%r15) | ||
76 | br %r14 | ||
77 | |||
78 | #endif | ||
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index cbb897bc50bd..9ed13a1ed376 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c | |||
@@ -156,15 +156,11 @@ __setup("condev=", condev_setup); | |||
156 | 156 | ||
157 | static void __init set_preferred_console(void) | 157 | static void __init set_preferred_console(void) |
158 | { | 158 | { |
159 | if (MACHINE_IS_KVM) { | 159 | if (MACHINE_IS_KVM) |
160 | add_preferred_console("hvc", 0, NULL); | 160 | add_preferred_console("hvc", 0, NULL); |
161 | s390_virtio_console_init(); | 161 | else if (CONSOLE_IS_3215 || CONSOLE_IS_SCLP) |
162 | return; | ||
163 | } | ||
164 | |||
165 | if (CONSOLE_IS_3215 || CONSOLE_IS_SCLP) | ||
166 | add_preferred_console("ttyS", 0, NULL); | 162 | add_preferred_console("ttyS", 0, NULL); |
167 | if (CONSOLE_IS_3270) | 163 | else if (CONSOLE_IS_3270) |
168 | add_preferred_console("tty3270", 0, NULL); | 164 | add_preferred_console("tty3270", 0, NULL); |
169 | } | 165 | } |
170 | 166 | ||
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index be2cae083406..56c16876b919 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c | |||
@@ -49,6 +49,7 @@ | |||
49 | #include <asm/sclp.h> | 49 | #include <asm/sclp.h> |
50 | #include <asm/cputime.h> | 50 | #include <asm/cputime.h> |
51 | #include <asm/vdso.h> | 51 | #include <asm/vdso.h> |
52 | #include <asm/cpu.h> | ||
52 | #include "entry.h" | 53 | #include "entry.h" |
53 | 54 | ||
54 | static struct task_struct *current_set[NR_CPUS]; | 55 | static struct task_struct *current_set[NR_CPUS]; |
@@ -70,6 +71,23 @@ static DEFINE_PER_CPU(struct cpu, cpu_devices); | |||
70 | 71 | ||
71 | static void smp_ext_bitcall(int, ec_bit_sig); | 72 | static void smp_ext_bitcall(int, ec_bit_sig); |
72 | 73 | ||
74 | static int cpu_stopped(int cpu) | ||
75 | { | ||
76 | __u32 status; | ||
77 | |||
78 | switch (signal_processor_ps(&status, 0, cpu, sigp_sense)) { | ||
79 | case sigp_order_code_accepted: | ||
80 | case sigp_status_stored: | ||
81 | /* Check for stopped and check stop state */ | ||
82 | if (status & 0x50) | ||
83 | return 1; | ||
84 | break; | ||
85 | default: | ||
86 | break; | ||
87 | } | ||
88 | return 0; | ||
89 | } | ||
90 | |||
73 | void smp_send_stop(void) | 91 | void smp_send_stop(void) |
74 | { | 92 | { |
75 | int cpu, rc; | 93 | int cpu, rc; |
@@ -86,7 +104,7 @@ void smp_send_stop(void) | |||
86 | rc = signal_processor(cpu, sigp_stop); | 104 | rc = signal_processor(cpu, sigp_stop); |
87 | } while (rc == sigp_busy); | 105 | } while (rc == sigp_busy); |
88 | 106 | ||
89 | while (!smp_cpu_not_running(cpu)) | 107 | while (!cpu_stopped(cpu)) |
90 | cpu_relax(); | 108 | cpu_relax(); |
91 | } | 109 | } |
92 | } | 110 | } |
@@ -269,19 +287,6 @@ static inline void smp_get_save_area(unsigned int cpu, unsigned int phy_cpu) { } | |||
269 | 287 | ||
270 | #endif /* CONFIG_ZFCPDUMP */ | 288 | #endif /* CONFIG_ZFCPDUMP */ |
271 | 289 | ||
272 | static int cpu_stopped(int cpu) | ||
273 | { | ||
274 | __u32 status; | ||
275 | |||
276 | /* Check for stopped state */ | ||
277 | if (signal_processor_ps(&status, 0, cpu, sigp_sense) == | ||
278 | sigp_status_stored) { | ||
279 | if (status & 0x40) | ||
280 | return 1; | ||
281 | } | ||
282 | return 0; | ||
283 | } | ||
284 | |||
285 | static int cpu_known(int cpu_id) | 290 | static int cpu_known(int cpu_id) |
286 | { | 291 | { |
287 | int cpu; | 292 | int cpu; |
@@ -300,7 +305,7 @@ static int smp_rescan_cpus_sigp(cpumask_t avail) | |||
300 | logical_cpu = cpumask_first(&avail); | 305 | logical_cpu = cpumask_first(&avail); |
301 | if (logical_cpu >= nr_cpu_ids) | 306 | if (logical_cpu >= nr_cpu_ids) |
302 | return 0; | 307 | return 0; |
303 | for (cpu_id = 0; cpu_id <= 65535; cpu_id++) { | 308 | for (cpu_id = 0; cpu_id <= MAX_CPU_ADDRESS; cpu_id++) { |
304 | if (cpu_known(cpu_id)) | 309 | if (cpu_known(cpu_id)) |
305 | continue; | 310 | continue; |
306 | __cpu_logical_map[logical_cpu] = cpu_id; | 311 | __cpu_logical_map[logical_cpu] = cpu_id; |
@@ -379,7 +384,7 @@ static void __init smp_detect_cpus(void) | |||
379 | /* Use sigp detection algorithm if sclp doesn't work. */ | 384 | /* Use sigp detection algorithm if sclp doesn't work. */ |
380 | if (sclp_get_cpu_info(info)) { | 385 | if (sclp_get_cpu_info(info)) { |
381 | smp_use_sigp_detection = 1; | 386 | smp_use_sigp_detection = 1; |
382 | for (cpu = 0; cpu <= 65535; cpu++) { | 387 | for (cpu = 0; cpu <= MAX_CPU_ADDRESS; cpu++) { |
383 | if (cpu == boot_cpu_addr) | 388 | if (cpu == boot_cpu_addr) |
384 | continue; | 389 | continue; |
385 | __cpu_logical_map[CPU_INIT_NO] = cpu; | 390 | __cpu_logical_map[CPU_INIT_NO] = cpu; |
@@ -635,7 +640,7 @@ int __cpu_disable(void) | |||
635 | void __cpu_die(unsigned int cpu) | 640 | void __cpu_die(unsigned int cpu) |
636 | { | 641 | { |
637 | /* Wait until target cpu is down */ | 642 | /* Wait until target cpu is down */ |
638 | while (!smp_cpu_not_running(cpu)) | 643 | while (!cpu_stopped(cpu)) |
639 | cpu_relax(); | 644 | cpu_relax(); |
640 | smp_free_lowcore(cpu); | 645 | smp_free_lowcore(cpu); |
641 | pr_info("Processor %d stopped\n", cpu); | 646 | pr_info("Processor %d stopped\n", cpu); |
diff --git a/arch/s390/power/swsusp.c b/arch/s390/kernel/suspend.c index bd1f5c6b0b8c..086bee970cae 100644 --- a/arch/s390/power/swsusp.c +++ b/arch/s390/kernel/suspend.c | |||
@@ -1,13 +1,44 @@ | |||
1 | /* | 1 | /* |
2 | * Support for suspend and resume on s390 | 2 | * Suspend support specific for s390. |
3 | * | 3 | * |
4 | * Copyright IBM Corp. 2009 | 4 | * Copyright IBM Corp. 2009 |
5 | * | 5 | * |
6 | * Author(s): Hans-Joachim Picht <hans@linux.vnet.ibm.com> | 6 | * Author(s): Hans-Joachim Picht <hans@linux.vnet.ibm.com> |
7 | * | ||
8 | */ | 7 | */ |
9 | 8 | ||
9 | #include <linux/suspend.h> | ||
10 | #include <linux/reboot.h> | ||
11 | #include <linux/pfn.h> | ||
12 | #include <linux/mm.h> | ||
13 | #include <asm/sections.h> | ||
10 | #include <asm/system.h> | 14 | #include <asm/system.h> |
15 | #include <asm/ipl.h> | ||
16 | |||
17 | /* | ||
18 | * References to section boundaries | ||
19 | */ | ||
20 | extern const void __nosave_begin, __nosave_end; | ||
21 | |||
22 | /* | ||
23 | * check if given pfn is in the 'nosave' or in the read only NSS section | ||
24 | */ | ||
25 | int pfn_is_nosave(unsigned long pfn) | ||
26 | { | ||
27 | unsigned long nosave_begin_pfn = __pa(&__nosave_begin) >> PAGE_SHIFT; | ||
28 | unsigned long nosave_end_pfn = PAGE_ALIGN(__pa(&__nosave_end)) | ||
29 | >> PAGE_SHIFT; | ||
30 | unsigned long eshared_pfn = PFN_DOWN(__pa(&_eshared)) - 1; | ||
31 | unsigned long stext_pfn = PFN_DOWN(__pa(&_stext)); | ||
32 | |||
33 | if (pfn >= nosave_begin_pfn && pfn < nosave_end_pfn) | ||
34 | return 1; | ||
35 | if (pfn >= stext_pfn && pfn <= eshared_pfn) { | ||
36 | if (ipl_info.type == IPL_TYPE_NSS) | ||
37 | return 1; | ||
38 | } else if ((tprot(pfn * PAGE_SIZE) && pfn > 0)) | ||
39 | return 1; | ||
40 | return 0; | ||
41 | } | ||
11 | 42 | ||
12 | void save_processor_state(void) | 43 | void save_processor_state(void) |
13 | { | 44 | { |
diff --git a/arch/s390/power/swsusp_asm64.S b/arch/s390/kernel/swsusp_asm64.S index b26df5c5933e..7cd6b096f0d1 100644 --- a/arch/s390/power/swsusp_asm64.S +++ b/arch/s390/kernel/swsusp_asm64.S | |||
@@ -21,7 +21,7 @@ | |||
21 | * This function runs with disabled interrupts. | 21 | * This function runs with disabled interrupts. |
22 | */ | 22 | */ |
23 | .section .text | 23 | .section .text |
24 | .align 2 | 24 | .align 4 |
25 | .globl swsusp_arch_suspend | 25 | .globl swsusp_arch_suspend |
26 | swsusp_arch_suspend: | 26 | swsusp_arch_suspend: |
27 | stmg %r6,%r15,__SF_GPRS(%r15) | 27 | stmg %r6,%r15,__SF_GPRS(%r15) |
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index d4c8e9c47c81..54e327e9af04 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c | |||
@@ -60,6 +60,7 @@ | |||
60 | #define TICK_SIZE tick | 60 | #define TICK_SIZE tick |
61 | 61 | ||
62 | u64 sched_clock_base_cc = -1; /* Force to data section. */ | 62 | u64 sched_clock_base_cc = -1; /* Force to data section. */ |
63 | EXPORT_SYMBOL_GPL(sched_clock_base_cc); | ||
63 | 64 | ||
64 | static DEFINE_PER_CPU(struct clock_event_device, comparators); | 65 | static DEFINE_PER_CPU(struct clock_event_device, comparators); |
65 | 66 | ||
@@ -68,7 +69,7 @@ static DEFINE_PER_CPU(struct clock_event_device, comparators); | |||
68 | */ | 69 | */ |
69 | unsigned long long notrace sched_clock(void) | 70 | unsigned long long notrace sched_clock(void) |
70 | { | 71 | { |
71 | return ((get_clock_xt() - sched_clock_base_cc) * 125) >> 9; | 72 | return (get_clock_monotonic() * 125) >> 9; |
72 | } | 73 | } |
73 | 74 | ||
74 | /* | 75 | /* |
diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S index a53db23ee092..7315f9e67e1d 100644 --- a/arch/s390/kernel/vmlinux.lds.S +++ b/arch/s390/kernel/vmlinux.lds.S | |||
@@ -52,55 +52,18 @@ SECTIONS | |||
52 | . = ALIGN(PAGE_SIZE); | 52 | . = ALIGN(PAGE_SIZE); |
53 | _eshared = .; /* End of shareable data */ | 53 | _eshared = .; /* End of shareable data */ |
54 | 54 | ||
55 | . = ALIGN(16); /* Exception table */ | 55 | EXCEPTION_TABLE(16) :data |
56 | __ex_table : { | ||
57 | __start___ex_table = .; | ||
58 | *(__ex_table) | ||
59 | __stop___ex_table = .; | ||
60 | } :data | ||
61 | |||
62 | .data : { /* Data */ | ||
63 | DATA_DATA | ||
64 | CONSTRUCTORS | ||
65 | } | ||
66 | |||
67 | . = ALIGN(PAGE_SIZE); | ||
68 | .data_nosave : { | ||
69 | __nosave_begin = .; | ||
70 | *(.data.nosave) | ||
71 | } | ||
72 | . = ALIGN(PAGE_SIZE); | ||
73 | __nosave_end = .; | ||
74 | |||
75 | . = ALIGN(PAGE_SIZE); | ||
76 | .data.page_aligned : { | ||
77 | *(.data.idt) | ||
78 | } | ||
79 | 56 | ||
80 | . = ALIGN(0x100); | 57 | RW_DATA_SECTION(0x100, PAGE_SIZE, THREAD_SIZE) |
81 | .data.cacheline_aligned : { | ||
82 | *(.data.cacheline_aligned) | ||
83 | } | ||
84 | 58 | ||
85 | . = ALIGN(0x100); | ||
86 | .data.read_mostly : { | ||
87 | *(.data.read_mostly) | ||
88 | } | ||
89 | _edata = .; /* End of data section */ | 59 | _edata = .; /* End of data section */ |
90 | 60 | ||
91 | . = ALIGN(THREAD_SIZE); /* init_task */ | ||
92 | .data.init_task : { | ||
93 | *(.data.init_task) | ||
94 | } | ||
95 | |||
96 | /* will be freed after init */ | 61 | /* will be freed after init */ |
97 | . = ALIGN(PAGE_SIZE); /* Init code and data */ | 62 | . = ALIGN(PAGE_SIZE); /* Init code and data */ |
98 | __init_begin = .; | 63 | __init_begin = .; |
99 | .init.text : { | 64 | |
100 | _sinittext = .; | 65 | INIT_TEXT_SECTION(PAGE_SIZE) |
101 | INIT_TEXT | 66 | |
102 | _einittext = .; | ||
103 | } | ||
104 | /* | 67 | /* |
105 | * .exit.text is discarded at runtime, not link time, | 68 | * .exit.text is discarded at runtime, not link time, |
106 | * to deal with references from __bug_table | 69 | * to deal with references from __bug_table |
@@ -111,49 +74,13 @@ SECTIONS | |||
111 | 74 | ||
112 | /* early.c uses stsi, which requires page aligned data. */ | 75 | /* early.c uses stsi, which requires page aligned data. */ |
113 | . = ALIGN(PAGE_SIZE); | 76 | . = ALIGN(PAGE_SIZE); |
114 | .init.data : { | 77 | INIT_DATA_SECTION(0x100) |
115 | INIT_DATA | ||
116 | } | ||
117 | . = ALIGN(0x100); | ||
118 | .init.setup : { | ||
119 | __setup_start = .; | ||
120 | *(.init.setup) | ||
121 | __setup_end = .; | ||
122 | } | ||
123 | .initcall.init : { | ||
124 | __initcall_start = .; | ||
125 | INITCALLS | ||
126 | __initcall_end = .; | ||
127 | } | ||
128 | |||
129 | .con_initcall.init : { | ||
130 | __con_initcall_start = .; | ||
131 | *(.con_initcall.init) | ||
132 | __con_initcall_end = .; | ||
133 | } | ||
134 | SECURITY_INIT | ||
135 | |||
136 | #ifdef CONFIG_BLK_DEV_INITRD | ||
137 | . = ALIGN(0x100); | ||
138 | .init.ramfs : { | ||
139 | __initramfs_start = .; | ||
140 | *(.init.ramfs) | ||
141 | . = ALIGN(2); | ||
142 | __initramfs_end = .; | ||
143 | } | ||
144 | #endif | ||
145 | 78 | ||
146 | PERCPU(PAGE_SIZE) | 79 | PERCPU(PAGE_SIZE) |
147 | . = ALIGN(PAGE_SIZE); | 80 | . = ALIGN(PAGE_SIZE); |
148 | __init_end = .; /* freed after init ends here */ | 81 | __init_end = .; /* freed after init ends here */ |
149 | 82 | ||
150 | /* BSS */ | 83 | BSS_SECTION(0, 2, 0) |
151 | .bss : { | ||
152 | __bss_start = .; | ||
153 | *(.bss) | ||
154 | . = ALIGN(2); | ||
155 | __bss_stop = .; | ||
156 | } | ||
157 | 84 | ||
158 | _end = . ; | 85 | _end = . ; |
159 | 86 | ||
diff --git a/arch/s390/mm/Makefile b/arch/s390/mm/Makefile index db05661ac895..eec054484419 100644 --- a/arch/s390/mm/Makefile +++ b/arch/s390/mm/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | # Makefile for the linux s390-specific parts of the memory manager. | 2 | # Makefile for the linux s390-specific parts of the memory manager. |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y := init.o fault.o extmem.o mmap.o vmem.o pgtable.o maccess.o | 5 | obj-y := init.o fault.o extmem.o mmap.o vmem.o pgtable.o maccess.o \ |
6 | page-states.o | ||
6 | obj-$(CONFIG_CMM) += cmm.o | 7 | obj-$(CONFIG_CMM) += cmm.o |
7 | obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o | 8 | obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o |
8 | obj-$(CONFIG_PAGE_STATES) += page-states.o | ||
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index e5e119fe03b2..1abbadd497e1 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c | |||
@@ -10,6 +10,7 @@ | |||
10 | * Copyright (C) 1995 Linus Torvalds | 10 | * Copyright (C) 1995 Linus Torvalds |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/perf_counter.h> | ||
13 | #include <linux/signal.h> | 14 | #include <linux/signal.h> |
14 | #include <linux/sched.h> | 15 | #include <linux/sched.h> |
15 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
@@ -305,7 +306,7 @@ do_exception(struct pt_regs *regs, unsigned long error_code, int write) | |||
305 | * interrupts again and then search the VMAs | 306 | * interrupts again and then search the VMAs |
306 | */ | 307 | */ |
307 | local_irq_enable(); | 308 | local_irq_enable(); |
308 | 309 | perf_swcounter_event(PERF_COUNT_SW_PAGE_FAULTS, 1, 0, regs, address); | |
309 | down_read(&mm->mmap_sem); | 310 | down_read(&mm->mmap_sem); |
310 | 311 | ||
311 | si_code = SEGV_MAPERR; | 312 | si_code = SEGV_MAPERR; |
@@ -363,11 +364,15 @@ good_area: | |||
363 | } | 364 | } |
364 | BUG(); | 365 | BUG(); |
365 | } | 366 | } |
366 | if (fault & VM_FAULT_MAJOR) | 367 | if (fault & VM_FAULT_MAJOR) { |
367 | tsk->maj_flt++; | 368 | tsk->maj_flt++; |
368 | else | 369 | perf_swcounter_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, 0, |
370 | regs, address); | ||
371 | } else { | ||
369 | tsk->min_flt++; | 372 | tsk->min_flt++; |
370 | 373 | perf_swcounter_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, 0, | |
374 | regs, address); | ||
375 | } | ||
371 | up_read(&mm->mmap_sem); | 376 | up_read(&mm->mmap_sem); |
372 | /* | 377 | /* |
373 | * The instruction that caused the program check will | 378 | * The instruction that caused the program check will |
diff --git a/arch/s390/mm/page-states.c b/arch/s390/mm/page-states.c index fc0ad73ffd90..f92ec203ad92 100644 --- a/arch/s390/mm/page-states.c +++ b/arch/s390/mm/page-states.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * arch/s390/mm/page-states.c | ||
3 | * | ||
4 | * Copyright IBM Corp. 2008 | 2 | * Copyright IBM Corp. 2008 |
5 | * | 3 | * |
6 | * Guest page hinting for unused pages. | 4 | * Guest page hinting for unused pages. |
@@ -17,11 +15,12 @@ | |||
17 | #define ESSA_SET_STABLE 1 | 15 | #define ESSA_SET_STABLE 1 |
18 | #define ESSA_SET_UNUSED 2 | 16 | #define ESSA_SET_UNUSED 2 |
19 | 17 | ||
20 | static int cmma_flag; | 18 | static int cmma_flag = 1; |
21 | 19 | ||
22 | static int __init cmma(char *str) | 20 | static int __init cmma(char *str) |
23 | { | 21 | { |
24 | char *parm; | 22 | char *parm; |
23 | |||
25 | parm = strstrip(str); | 24 | parm = strstrip(str); |
26 | if (strcmp(parm, "yes") == 0 || strcmp(parm, "on") == 0) { | 25 | if (strcmp(parm, "yes") == 0 || strcmp(parm, "on") == 0) { |
27 | cmma_flag = 1; | 26 | cmma_flag = 1; |
@@ -32,7 +31,6 @@ static int __init cmma(char *str) | |||
32 | return 1; | 31 | return 1; |
33 | return 0; | 32 | return 0; |
34 | } | 33 | } |
35 | |||
36 | __setup("cmma=", cmma); | 34 | __setup("cmma=", cmma); |
37 | 35 | ||
38 | void __init cmma_init(void) | 36 | void __init cmma_init(void) |
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index 565667207985..c70215247071 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c | |||
@@ -78,9 +78,9 @@ unsigned long *crst_table_alloc(struct mm_struct *mm, int noexec) | |||
78 | } | 78 | } |
79 | page->index = page_to_phys(shadow); | 79 | page->index = page_to_phys(shadow); |
80 | } | 80 | } |
81 | spin_lock(&mm->page_table_lock); | 81 | spin_lock(&mm->context.list_lock); |
82 | list_add(&page->lru, &mm->context.crst_list); | 82 | list_add(&page->lru, &mm->context.crst_list); |
83 | spin_unlock(&mm->page_table_lock); | 83 | spin_unlock(&mm->context.list_lock); |
84 | return (unsigned long *) page_to_phys(page); | 84 | return (unsigned long *) page_to_phys(page); |
85 | } | 85 | } |
86 | 86 | ||
@@ -89,9 +89,9 @@ void crst_table_free(struct mm_struct *mm, unsigned long *table) | |||
89 | unsigned long *shadow = get_shadow_table(table); | 89 | unsigned long *shadow = get_shadow_table(table); |
90 | struct page *page = virt_to_page(table); | 90 | struct page *page = virt_to_page(table); |
91 | 91 | ||
92 | spin_lock(&mm->page_table_lock); | 92 | spin_lock(&mm->context.list_lock); |
93 | list_del(&page->lru); | 93 | list_del(&page->lru); |
94 | spin_unlock(&mm->page_table_lock); | 94 | spin_unlock(&mm->context.list_lock); |
95 | if (shadow) | 95 | if (shadow) |
96 | free_pages((unsigned long) shadow, ALLOC_ORDER); | 96 | free_pages((unsigned long) shadow, ALLOC_ORDER); |
97 | free_pages((unsigned long) table, ALLOC_ORDER); | 97 | free_pages((unsigned long) table, ALLOC_ORDER); |
@@ -182,7 +182,7 @@ unsigned long *page_table_alloc(struct mm_struct *mm) | |||
182 | unsigned long bits; | 182 | unsigned long bits; |
183 | 183 | ||
184 | bits = (mm->context.noexec || mm->context.has_pgste) ? 3UL : 1UL; | 184 | bits = (mm->context.noexec || mm->context.has_pgste) ? 3UL : 1UL; |
185 | spin_lock(&mm->page_table_lock); | 185 | spin_lock(&mm->context.list_lock); |
186 | page = NULL; | 186 | page = NULL; |
187 | if (!list_empty(&mm->context.pgtable_list)) { | 187 | if (!list_empty(&mm->context.pgtable_list)) { |
188 | page = list_first_entry(&mm->context.pgtable_list, | 188 | page = list_first_entry(&mm->context.pgtable_list, |
@@ -191,7 +191,7 @@ unsigned long *page_table_alloc(struct mm_struct *mm) | |||
191 | page = NULL; | 191 | page = NULL; |
192 | } | 192 | } |
193 | if (!page) { | 193 | if (!page) { |
194 | spin_unlock(&mm->page_table_lock); | 194 | spin_unlock(&mm->context.list_lock); |
195 | page = alloc_page(GFP_KERNEL|__GFP_REPEAT); | 195 | page = alloc_page(GFP_KERNEL|__GFP_REPEAT); |
196 | if (!page) | 196 | if (!page) |
197 | return NULL; | 197 | return NULL; |
@@ -202,7 +202,7 @@ unsigned long *page_table_alloc(struct mm_struct *mm) | |||
202 | clear_table_pgstes(table); | 202 | clear_table_pgstes(table); |
203 | else | 203 | else |
204 | clear_table(table, _PAGE_TYPE_EMPTY, PAGE_SIZE); | 204 | clear_table(table, _PAGE_TYPE_EMPTY, PAGE_SIZE); |
205 | spin_lock(&mm->page_table_lock); | 205 | spin_lock(&mm->context.list_lock); |
206 | list_add(&page->lru, &mm->context.pgtable_list); | 206 | list_add(&page->lru, &mm->context.pgtable_list); |
207 | } | 207 | } |
208 | table = (unsigned long *) page_to_phys(page); | 208 | table = (unsigned long *) page_to_phys(page); |
@@ -213,7 +213,7 @@ unsigned long *page_table_alloc(struct mm_struct *mm) | |||
213 | page->flags |= bits; | 213 | page->flags |= bits; |
214 | if ((page->flags & FRAG_MASK) == ((1UL << TABLES_PER_PAGE) - 1)) | 214 | if ((page->flags & FRAG_MASK) == ((1UL << TABLES_PER_PAGE) - 1)) |
215 | list_move_tail(&page->lru, &mm->context.pgtable_list); | 215 | list_move_tail(&page->lru, &mm->context.pgtable_list); |
216 | spin_unlock(&mm->page_table_lock); | 216 | spin_unlock(&mm->context.list_lock); |
217 | return table; | 217 | return table; |
218 | } | 218 | } |
219 | 219 | ||
@@ -225,7 +225,7 @@ void page_table_free(struct mm_struct *mm, unsigned long *table) | |||
225 | bits = (mm->context.noexec || mm->context.has_pgste) ? 3UL : 1UL; | 225 | bits = (mm->context.noexec || mm->context.has_pgste) ? 3UL : 1UL; |
226 | bits <<= (__pa(table) & (PAGE_SIZE - 1)) / 256 / sizeof(unsigned long); | 226 | bits <<= (__pa(table) & (PAGE_SIZE - 1)) / 256 / sizeof(unsigned long); |
227 | page = pfn_to_page(__pa(table) >> PAGE_SHIFT); | 227 | page = pfn_to_page(__pa(table) >> PAGE_SHIFT); |
228 | spin_lock(&mm->page_table_lock); | 228 | spin_lock(&mm->context.list_lock); |
229 | page->flags ^= bits; | 229 | page->flags ^= bits; |
230 | if (page->flags & FRAG_MASK) { | 230 | if (page->flags & FRAG_MASK) { |
231 | /* Page now has some free pgtable fragments. */ | 231 | /* Page now has some free pgtable fragments. */ |
@@ -234,7 +234,7 @@ void page_table_free(struct mm_struct *mm, unsigned long *table) | |||
234 | } else | 234 | } else |
235 | /* All fragments of the 4K page have been freed. */ | 235 | /* All fragments of the 4K page have been freed. */ |
236 | list_del(&page->lru); | 236 | list_del(&page->lru); |
237 | spin_unlock(&mm->page_table_lock); | 237 | spin_unlock(&mm->context.list_lock); |
238 | if (page) { | 238 | if (page) { |
239 | pgtable_page_dtor(page); | 239 | pgtable_page_dtor(page); |
240 | __free_page(page); | 240 | __free_page(page); |
@@ -245,7 +245,7 @@ void disable_noexec(struct mm_struct *mm, struct task_struct *tsk) | |||
245 | { | 245 | { |
246 | struct page *page; | 246 | struct page *page; |
247 | 247 | ||
248 | spin_lock(&mm->page_table_lock); | 248 | spin_lock(&mm->context.list_lock); |
249 | /* Free shadow region and segment tables. */ | 249 | /* Free shadow region and segment tables. */ |
250 | list_for_each_entry(page, &mm->context.crst_list, lru) | 250 | list_for_each_entry(page, &mm->context.crst_list, lru) |
251 | if (page->index) { | 251 | if (page->index) { |
@@ -255,7 +255,7 @@ void disable_noexec(struct mm_struct *mm, struct task_struct *tsk) | |||
255 | /* "Free" second halves of page tables. */ | 255 | /* "Free" second halves of page tables. */ |
256 | list_for_each_entry(page, &mm->context.pgtable_list, lru) | 256 | list_for_each_entry(page, &mm->context.pgtable_list, lru) |
257 | page->flags &= ~SECOND_HALVES; | 257 | page->flags &= ~SECOND_HALVES; |
258 | spin_unlock(&mm->page_table_lock); | 258 | spin_unlock(&mm->context.list_lock); |
259 | mm->context.noexec = 0; | 259 | mm->context.noexec = 0; |
260 | update_mm(mm, tsk); | 260 | update_mm(mm, tsk); |
261 | } | 261 | } |
diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c index e4868bfc672f..5f91a38d7592 100644 --- a/arch/s390/mm/vmem.c +++ b/arch/s390/mm/vmem.c | |||
@@ -331,6 +331,7 @@ void __init vmem_map_init(void) | |||
331 | unsigned long start, end; | 331 | unsigned long start, end; |
332 | int i; | 332 | int i; |
333 | 333 | ||
334 | spin_lock_init(&init_mm.context.list_lock); | ||
334 | INIT_LIST_HEAD(&init_mm.context.crst_list); | 335 | INIT_LIST_HEAD(&init_mm.context.crst_list); |
335 | INIT_LIST_HEAD(&init_mm.context.pgtable_list); | 336 | INIT_LIST_HEAD(&init_mm.context.pgtable_list); |
336 | init_mm.context.noexec = 0; | 337 | init_mm.context.noexec = 0; |
diff --git a/arch/s390/power/Makefile b/arch/s390/power/Makefile deleted file mode 100644 index 973bb45a8fec..000000000000 --- a/arch/s390/power/Makefile +++ /dev/null | |||
@@ -1,8 +0,0 @@ | |||
1 | # | ||
2 | # Makefile for s390 PM support | ||
3 | # | ||
4 | |||
5 | obj-$(CONFIG_HIBERNATION) += suspend.o | ||
6 | obj-$(CONFIG_HIBERNATION) += swsusp.o | ||
7 | obj-$(CONFIG_HIBERNATION) += swsusp_64.o | ||
8 | obj-$(CONFIG_HIBERNATION) += swsusp_asm64.o | ||
diff --git a/arch/s390/power/suspend.c b/arch/s390/power/suspend.c deleted file mode 100644 index b3351eceebbe..000000000000 --- a/arch/s390/power/suspend.c +++ /dev/null | |||
@@ -1,40 +0,0 @@ | |||
1 | /* | ||
2 | * Suspend support specific for s390. | ||
3 | * | ||
4 | * Copyright IBM Corp. 2009 | ||
5 | * | ||
6 | * Author(s): Hans-Joachim Picht <hans@linux.vnet.ibm.com> | ||
7 | */ | ||
8 | |||
9 | #include <linux/mm.h> | ||
10 | #include <linux/suspend.h> | ||
11 | #include <linux/reboot.h> | ||
12 | #include <linux/pfn.h> | ||
13 | #include <asm/sections.h> | ||
14 | #include <asm/ipl.h> | ||
15 | |||
16 | /* | ||
17 | * References to section boundaries | ||
18 | */ | ||
19 | extern const void __nosave_begin, __nosave_end; | ||
20 | |||
21 | /* | ||
22 | * check if given pfn is in the 'nosave' or in the read only NSS section | ||
23 | */ | ||
24 | int pfn_is_nosave(unsigned long pfn) | ||
25 | { | ||
26 | unsigned long nosave_begin_pfn = __pa(&__nosave_begin) >> PAGE_SHIFT; | ||
27 | unsigned long nosave_end_pfn = PAGE_ALIGN(__pa(&__nosave_end)) | ||
28 | >> PAGE_SHIFT; | ||
29 | unsigned long eshared_pfn = PFN_DOWN(__pa(&_eshared)) - 1; | ||
30 | unsigned long stext_pfn = PFN_DOWN(__pa(&_stext)); | ||
31 | |||
32 | if (pfn >= nosave_begin_pfn && pfn < nosave_end_pfn) | ||
33 | return 1; | ||
34 | if (pfn >= stext_pfn && pfn <= eshared_pfn) { | ||
35 | if (ipl_info.type == IPL_TYPE_NSS) | ||
36 | return 1; | ||
37 | } else if ((tprot(pfn * PAGE_SIZE) && pfn > 0)) | ||
38 | return 1; | ||
39 | return 0; | ||
40 | } | ||
diff --git a/arch/s390/power/swsusp_64.c b/arch/s390/power/swsusp_64.c deleted file mode 100644 index 9516a517d72f..000000000000 --- a/arch/s390/power/swsusp_64.c +++ /dev/null | |||
@@ -1,17 +0,0 @@ | |||
1 | /* | ||
2 | * Support for suspend and resume on s390 | ||
3 | * | ||
4 | * Copyright IBM Corp. 2009 | ||
5 | * | ||
6 | * Author(s): Hans-Joachim Picht <hans@linux.vnet.ibm.com> | ||
7 | * | ||
8 | */ | ||
9 | |||
10 | #include <asm/system.h> | ||
11 | #include <linux/interrupt.h> | ||
12 | |||
13 | void do_after_copyback(void) | ||
14 | { | ||
15 | mb(); | ||
16 | } | ||
17 | |||