diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-25 20:47:04 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-25 20:47:04 -0400 |
commit | 7c8d891c2c7714965db1685289787b0c526f9c42 (patch) | |
tree | 63f4bb25df1a3b9798d318e8c2c28b959709f182 /arch/s390 | |
parent | 62d00867514ae1c81ab5e809e189ca159536daee (diff) | |
parent | 54eaae3028e6b09de0bd2232a8176fc0d0a2397a (diff) |
Merge branch 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6
* 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6:
[S390] cmpxchg: implement cmpxchg64()
[S390] xchg/cmpxchg: move to own header file
[S390] ccwgroup_driver: remove duplicate members
[S390] ccw_bus_type: make it static
[S390] ccw_driver: remove duplicate members
[S390] qdio: prevent handling of buffers if count is zero
[S390] setup: register bss section as resource
[S390] setup: simplify setup_resources()
[S390] wire up sys_syncfs
[S390] wire up sys_clock_adjtime
[S390] wire up sys_open_by_handle_at
[S390] wire up sys_name_to_handle_at
[S390] oprofile: disable hw sampling for CONFIG_32BIT
[S390] early: limit savesys cmd string handling
[S390] early: Fix possible overlapping data buffer
Diffstat (limited to 'arch/s390')
-rw-r--r-- | arch/s390/include/asm/ccwdev.h | 4 | ||||
-rw-r--r-- | arch/s390/include/asm/ccwgroup.h | 4 | ||||
-rw-r--r-- | arch/s390/include/asm/cmpxchg.h | 225 | ||||
-rw-r--r-- | arch/s390/include/asm/system.h | 196 | ||||
-rw-r--r-- | arch/s390/include/asm/unistd.h | 6 | ||||
-rw-r--r-- | arch/s390/kernel/compat_wrapper.S | 27 | ||||
-rw-r--r-- | arch/s390/kernel/early.c | 22 | ||||
-rw-r--r-- | arch/s390/kernel/setup.c | 88 | ||||
-rw-r--r-- | arch/s390/kernel/syscalls.S | 4 | ||||
-rw-r--r-- | arch/s390/oprofile/Makefile | 3 | ||||
-rw-r--r-- | arch/s390/oprofile/init.c | 15 |
11 files changed, 332 insertions, 262 deletions
diff --git a/arch/s390/include/asm/ccwdev.h b/arch/s390/include/asm/ccwdev.h index ff6f62e0ec3e..623f2fb71774 100644 --- a/arch/s390/include/asm/ccwdev.h +++ b/arch/s390/include/asm/ccwdev.h | |||
@@ -112,7 +112,6 @@ enum uc_todo { | |||
112 | 112 | ||
113 | /** | 113 | /** |
114 | * struct ccw driver - device driver for channel attached devices | 114 | * struct ccw driver - device driver for channel attached devices |
115 | * @owner: owning module | ||
116 | * @ids: ids supported by this driver | 115 | * @ids: ids supported by this driver |
117 | * @probe: function called on probe | 116 | * @probe: function called on probe |
118 | * @remove: function called on remove | 117 | * @remove: function called on remove |
@@ -128,10 +127,8 @@ enum uc_todo { | |||
128 | * @restore: callback for restoring after hibernation | 127 | * @restore: callback for restoring after hibernation |
129 | * @uc_handler: callback for unit check handler | 128 | * @uc_handler: callback for unit check handler |
130 | * @driver: embedded device driver structure | 129 | * @driver: embedded device driver structure |
131 | * @name: device driver name | ||
132 | */ | 130 | */ |
133 | struct ccw_driver { | 131 | struct ccw_driver { |
134 | struct module *owner; | ||
135 | struct ccw_device_id *ids; | 132 | struct ccw_device_id *ids; |
136 | int (*probe) (struct ccw_device *); | 133 | int (*probe) (struct ccw_device *); |
137 | void (*remove) (struct ccw_device *); | 134 | void (*remove) (struct ccw_device *); |
@@ -147,7 +144,6 @@ struct ccw_driver { | |||
147 | int (*restore)(struct ccw_device *); | 144 | int (*restore)(struct ccw_device *); |
148 | enum uc_todo (*uc_handler) (struct ccw_device *, struct irb *); | 145 | enum uc_todo (*uc_handler) (struct ccw_device *, struct irb *); |
149 | struct device_driver driver; | 146 | struct device_driver driver; |
150 | char *name; | ||
151 | }; | 147 | }; |
152 | 148 | ||
153 | extern struct ccw_device *get_ccwdev_by_busid(struct ccw_driver *cdrv, | 149 | extern struct ccw_device *get_ccwdev_by_busid(struct ccw_driver *cdrv, |
diff --git a/arch/s390/include/asm/ccwgroup.h b/arch/s390/include/asm/ccwgroup.h index c79c1e787b86..f2ea2c56a7e1 100644 --- a/arch/s390/include/asm/ccwgroup.h +++ b/arch/s390/include/asm/ccwgroup.h | |||
@@ -29,8 +29,6 @@ struct ccwgroup_device { | |||
29 | 29 | ||
30 | /** | 30 | /** |
31 | * struct ccwgroup_driver - driver for ccw group devices | 31 | * struct ccwgroup_driver - driver for ccw group devices |
32 | * @owner: driver owner | ||
33 | * @name: driver name | ||
34 | * @max_slaves: maximum number of slave devices | 32 | * @max_slaves: maximum number of slave devices |
35 | * @driver_id: unique id | 33 | * @driver_id: unique id |
36 | * @probe: function called on probe | 34 | * @probe: function called on probe |
@@ -46,8 +44,6 @@ struct ccwgroup_device { | |||
46 | * @driver: embedded driver structure | 44 | * @driver: embedded driver structure |
47 | */ | 45 | */ |
48 | struct ccwgroup_driver { | 46 | struct ccwgroup_driver { |
49 | struct module *owner; | ||
50 | char *name; | ||
51 | int max_slaves; | 47 | int max_slaves; |
52 | unsigned long driver_id; | 48 | unsigned long driver_id; |
53 | 49 | ||
diff --git a/arch/s390/include/asm/cmpxchg.h b/arch/s390/include/asm/cmpxchg.h new file mode 100644 index 000000000000..7488e52efa97 --- /dev/null +++ b/arch/s390/include/asm/cmpxchg.h | |||
@@ -0,0 +1,225 @@ | |||
1 | /* | ||
2 | * Copyright IBM Corp. 1999, 2011 | ||
3 | * | ||
4 | * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>, | ||
5 | */ | ||
6 | |||
7 | #ifndef __ASM_CMPXCHG_H | ||
8 | #define __ASM_CMPXCHG_H | ||
9 | |||
10 | #include <linux/types.h> | ||
11 | |||
12 | extern void __xchg_called_with_bad_pointer(void); | ||
13 | |||
14 | static inline unsigned long __xchg(unsigned long x, void *ptr, int size) | ||
15 | { | ||
16 | unsigned long addr, old; | ||
17 | int shift; | ||
18 | |||
19 | switch (size) { | ||
20 | case 1: | ||
21 | addr = (unsigned long) ptr; | ||
22 | shift = (3 ^ (addr & 3)) << 3; | ||
23 | addr ^= addr & 3; | ||
24 | asm volatile( | ||
25 | " l %0,%4\n" | ||
26 | "0: lr 0,%0\n" | ||
27 | " nr 0,%3\n" | ||
28 | " or 0,%2\n" | ||
29 | " cs %0,0,%4\n" | ||
30 | " jl 0b\n" | ||
31 | : "=&d" (old), "=Q" (*(int *) addr) | ||
32 | : "d" (x << shift), "d" (~(255 << shift)), | ||
33 | "Q" (*(int *) addr) : "memory", "cc", "0"); | ||
34 | return old >> shift; | ||
35 | case 2: | ||
36 | addr = (unsigned long) ptr; | ||
37 | shift = (2 ^ (addr & 2)) << 3; | ||
38 | addr ^= addr & 2; | ||
39 | asm volatile( | ||
40 | " l %0,%4\n" | ||
41 | "0: lr 0,%0\n" | ||
42 | " nr 0,%3\n" | ||
43 | " or 0,%2\n" | ||
44 | " cs %0,0,%4\n" | ||
45 | " jl 0b\n" | ||
46 | : "=&d" (old), "=Q" (*(int *) addr) | ||
47 | : "d" (x << shift), "d" (~(65535 << shift)), | ||
48 | "Q" (*(int *) addr) : "memory", "cc", "0"); | ||
49 | return old >> shift; | ||
50 | case 4: | ||
51 | asm volatile( | ||
52 | " l %0,%3\n" | ||
53 | "0: cs %0,%2,%3\n" | ||
54 | " jl 0b\n" | ||
55 | : "=&d" (old), "=Q" (*(int *) ptr) | ||
56 | : "d" (x), "Q" (*(int *) ptr) | ||
57 | : "memory", "cc"); | ||
58 | return old; | ||
59 | #ifdef CONFIG_64BIT | ||
60 | case 8: | ||
61 | asm volatile( | ||
62 | " lg %0,%3\n" | ||
63 | "0: csg %0,%2,%3\n" | ||
64 | " jl 0b\n" | ||
65 | : "=&d" (old), "=m" (*(long *) ptr) | ||
66 | : "d" (x), "Q" (*(long *) ptr) | ||
67 | : "memory", "cc"); | ||
68 | return old; | ||
69 | #endif /* CONFIG_64BIT */ | ||
70 | } | ||
71 | __xchg_called_with_bad_pointer(); | ||
72 | return x; | ||
73 | } | ||
74 | |||
75 | #define xchg(ptr, x) \ | ||
76 | ({ \ | ||
77 | __typeof__(*(ptr)) __ret; \ | ||
78 | __ret = (__typeof__(*(ptr))) \ | ||
79 | __xchg((unsigned long)(x), (void *)(ptr), sizeof(*(ptr)));\ | ||
80 | __ret; \ | ||
81 | }) | ||
82 | |||
83 | /* | ||
84 | * Atomic compare and exchange. Compare OLD with MEM, if identical, | ||
85 | * store NEW in MEM. Return the initial value in MEM. Success is | ||
86 | * indicated by comparing RETURN with OLD. | ||
87 | */ | ||
88 | |||
89 | #define __HAVE_ARCH_CMPXCHG | ||
90 | |||
91 | extern void __cmpxchg_called_with_bad_pointer(void); | ||
92 | |||
93 | static inline unsigned long __cmpxchg(void *ptr, unsigned long old, | ||
94 | unsigned long new, int size) | ||
95 | { | ||
96 | unsigned long addr, prev, tmp; | ||
97 | int shift; | ||
98 | |||
99 | switch (size) { | ||
100 | case 1: | ||
101 | addr = (unsigned long) ptr; | ||
102 | shift = (3 ^ (addr & 3)) << 3; | ||
103 | addr ^= addr & 3; | ||
104 | asm volatile( | ||
105 | " l %0,%2\n" | ||
106 | "0: nr %0,%5\n" | ||
107 | " lr %1,%0\n" | ||
108 | " or %0,%3\n" | ||
109 | " or %1,%4\n" | ||
110 | " cs %0,%1,%2\n" | ||
111 | " jnl 1f\n" | ||
112 | " xr %1,%0\n" | ||
113 | " nr %1,%5\n" | ||
114 | " jnz 0b\n" | ||
115 | "1:" | ||
116 | : "=&d" (prev), "=&d" (tmp), "=Q" (*(int *) ptr) | ||
117 | : "d" (old << shift), "d" (new << shift), | ||
118 | "d" (~(255 << shift)), "Q" (*(int *) ptr) | ||
119 | : "memory", "cc"); | ||
120 | return prev >> shift; | ||
121 | case 2: | ||
122 | addr = (unsigned long) ptr; | ||
123 | shift = (2 ^ (addr & 2)) << 3; | ||
124 | addr ^= addr & 2; | ||
125 | asm volatile( | ||
126 | " l %0,%2\n" | ||
127 | "0: nr %0,%5\n" | ||
128 | " lr %1,%0\n" | ||
129 | " or %0,%3\n" | ||
130 | " or %1,%4\n" | ||
131 | " cs %0,%1,%2\n" | ||
132 | " jnl 1f\n" | ||
133 | " xr %1,%0\n" | ||
134 | " nr %1,%5\n" | ||
135 | " jnz 0b\n" | ||
136 | "1:" | ||
137 | : "=&d" (prev), "=&d" (tmp), "=Q" (*(int *) ptr) | ||
138 | : "d" (old << shift), "d" (new << shift), | ||
139 | "d" (~(65535 << shift)), "Q" (*(int *) ptr) | ||
140 | : "memory", "cc"); | ||
141 | return prev >> shift; | ||
142 | case 4: | ||
143 | asm volatile( | ||
144 | " cs %0,%3,%1\n" | ||
145 | : "=&d" (prev), "=Q" (*(int *) ptr) | ||
146 | : "0" (old), "d" (new), "Q" (*(int *) ptr) | ||
147 | : "memory", "cc"); | ||
148 | return prev; | ||
149 | #ifdef CONFIG_64BIT | ||
150 | case 8: | ||
151 | asm volatile( | ||
152 | " csg %0,%3,%1\n" | ||
153 | : "=&d" (prev), "=Q" (*(long *) ptr) | ||
154 | : "0" (old), "d" (new), "Q" (*(long *) ptr) | ||
155 | : "memory", "cc"); | ||
156 | return prev; | ||
157 | #endif /* CONFIG_64BIT */ | ||
158 | } | ||
159 | __cmpxchg_called_with_bad_pointer(); | ||
160 | return old; | ||
161 | } | ||
162 | |||
163 | #define cmpxchg(ptr, o, n) \ | ||
164 | ((__typeof__(*(ptr)))__cmpxchg((ptr), (unsigned long)(o), \ | ||
165 | (unsigned long)(n), sizeof(*(ptr)))) | ||
166 | |||
167 | #ifdef CONFIG_64BIT | ||
168 | #define cmpxchg64(ptr, o, n) \ | ||
169 | ({ \ | ||
170 | BUILD_BUG_ON(sizeof(*(ptr)) != 8); \ | ||
171 | cmpxchg((ptr), (o), (n)); \ | ||
172 | }) | ||
173 | #else /* CONFIG_64BIT */ | ||
174 | static inline unsigned long long __cmpxchg64(void *ptr, | ||
175 | unsigned long long old, | ||
176 | unsigned long long new) | ||
177 | { | ||
178 | register_pair rp_old = {.pair = old}; | ||
179 | register_pair rp_new = {.pair = new}; | ||
180 | |||
181 | asm volatile( | ||
182 | " cds %0,%2,%1" | ||
183 | : "+&d" (rp_old), "=Q" (ptr) | ||
184 | : "d" (rp_new), "Q" (ptr) | ||
185 | : "cc"); | ||
186 | return rp_old.pair; | ||
187 | } | ||
188 | #define cmpxchg64(ptr, o, n) \ | ||
189 | ((__typeof__(*(ptr)))__cmpxchg64((ptr), \ | ||
190 | (unsigned long long)(o), \ | ||
191 | (unsigned long long)(n))) | ||
192 | #endif /* CONFIG_64BIT */ | ||
193 | |||
194 | #include <asm-generic/cmpxchg-local.h> | ||
195 | |||
196 | static inline unsigned long __cmpxchg_local(void *ptr, | ||
197 | unsigned long old, | ||
198 | unsigned long new, int size) | ||
199 | { | ||
200 | switch (size) { | ||
201 | case 1: | ||
202 | case 2: | ||
203 | case 4: | ||
204 | #ifdef CONFIG_64BIT | ||
205 | case 8: | ||
206 | #endif | ||
207 | return __cmpxchg(ptr, old, new, size); | ||
208 | default: | ||
209 | return __cmpxchg_local_generic(ptr, old, new, size); | ||
210 | } | ||
211 | |||
212 | return old; | ||
213 | } | ||
214 | |||
215 | /* | ||
216 | * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make | ||
217 | * them available. | ||
218 | */ | ||
219 | #define cmpxchg_local(ptr, o, n) \ | ||
220 | ((__typeof__(*(ptr)))__cmpxchg_local((ptr), (unsigned long)(o), \ | ||
221 | (unsigned long)(n), sizeof(*(ptr)))) | ||
222 | |||
223 | #define cmpxchg64_local(ptr, o, n) cmpxchg64((ptr), (o), (n)) | ||
224 | |||
225 | #endif /* __ASM_CMPXCHG_H */ | ||
diff --git a/arch/s390/include/asm/system.h b/arch/s390/include/asm/system.h index 8f8d759f6a7b..d382629a0172 100644 --- a/arch/s390/include/asm/system.h +++ b/arch/s390/include/asm/system.h | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <asm/setup.h> | 14 | #include <asm/setup.h> |
15 | #include <asm/processor.h> | 15 | #include <asm/processor.h> |
16 | #include <asm/lowcore.h> | 16 | #include <asm/lowcore.h> |
17 | #include <asm/cmpxchg.h> | ||
17 | 18 | ||
18 | #ifdef __KERNEL__ | 19 | #ifdef __KERNEL__ |
19 | 20 | ||
@@ -120,161 +121,6 @@ extern int memcpy_real(void *, void *, size_t); | |||
120 | 121 | ||
121 | #define nop() asm volatile("nop") | 122 | #define nop() asm volatile("nop") |
122 | 123 | ||
123 | #define xchg(ptr,x) \ | ||
124 | ({ \ | ||
125 | __typeof__(*(ptr)) __ret; \ | ||
126 | __ret = (__typeof__(*(ptr))) \ | ||
127 | __xchg((unsigned long)(x), (void *)(ptr),sizeof(*(ptr))); \ | ||
128 | __ret; \ | ||
129 | }) | ||
130 | |||
131 | extern void __xchg_called_with_bad_pointer(void); | ||
132 | |||
133 | static inline unsigned long __xchg(unsigned long x, void * ptr, int size) | ||
134 | { | ||
135 | unsigned long addr, old; | ||
136 | int shift; | ||
137 | |||
138 | switch (size) { | ||
139 | case 1: | ||
140 | addr = (unsigned long) ptr; | ||
141 | shift = (3 ^ (addr & 3)) << 3; | ||
142 | addr ^= addr & 3; | ||
143 | asm volatile( | ||
144 | " l %0,%4\n" | ||
145 | "0: lr 0,%0\n" | ||
146 | " nr 0,%3\n" | ||
147 | " or 0,%2\n" | ||
148 | " cs %0,0,%4\n" | ||
149 | " jl 0b\n" | ||
150 | : "=&d" (old), "=Q" (*(int *) addr) | ||
151 | : "d" (x << shift), "d" (~(255 << shift)), | ||
152 | "Q" (*(int *) addr) : "memory", "cc", "0"); | ||
153 | return old >> shift; | ||
154 | case 2: | ||
155 | addr = (unsigned long) ptr; | ||
156 | shift = (2 ^ (addr & 2)) << 3; | ||
157 | addr ^= addr & 2; | ||
158 | asm volatile( | ||
159 | " l %0,%4\n" | ||
160 | "0: lr 0,%0\n" | ||
161 | " nr 0,%3\n" | ||
162 | " or 0,%2\n" | ||
163 | " cs %0,0,%4\n" | ||
164 | " jl 0b\n" | ||
165 | : "=&d" (old), "=Q" (*(int *) addr) | ||
166 | : "d" (x << shift), "d" (~(65535 << shift)), | ||
167 | "Q" (*(int *) addr) : "memory", "cc", "0"); | ||
168 | return old >> shift; | ||
169 | case 4: | ||
170 | asm volatile( | ||
171 | " l %0,%3\n" | ||
172 | "0: cs %0,%2,%3\n" | ||
173 | " jl 0b\n" | ||
174 | : "=&d" (old), "=Q" (*(int *) ptr) | ||
175 | : "d" (x), "Q" (*(int *) ptr) | ||
176 | : "memory", "cc"); | ||
177 | return old; | ||
178 | #ifdef __s390x__ | ||
179 | case 8: | ||
180 | asm volatile( | ||
181 | " lg %0,%3\n" | ||
182 | "0: csg %0,%2,%3\n" | ||
183 | " jl 0b\n" | ||
184 | : "=&d" (old), "=m" (*(long *) ptr) | ||
185 | : "d" (x), "Q" (*(long *) ptr) | ||
186 | : "memory", "cc"); | ||
187 | return old; | ||
188 | #endif /* __s390x__ */ | ||
189 | } | ||
190 | __xchg_called_with_bad_pointer(); | ||
191 | return x; | ||
192 | } | ||
193 | |||
194 | /* | ||
195 | * Atomic compare and exchange. Compare OLD with MEM, if identical, | ||
196 | * store NEW in MEM. Return the initial value in MEM. Success is | ||
197 | * indicated by comparing RETURN with OLD. | ||
198 | */ | ||
199 | |||
200 | #define __HAVE_ARCH_CMPXCHG 1 | ||
201 | |||
202 | #define cmpxchg(ptr, o, n) \ | ||
203 | ((__typeof__(*(ptr)))__cmpxchg((ptr), (unsigned long)(o), \ | ||
204 | (unsigned long)(n), sizeof(*(ptr)))) | ||
205 | |||
206 | extern void __cmpxchg_called_with_bad_pointer(void); | ||
207 | |||
208 | static inline unsigned long | ||
209 | __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) | ||
210 | { | ||
211 | unsigned long addr, prev, tmp; | ||
212 | int shift; | ||
213 | |||
214 | switch (size) { | ||
215 | case 1: | ||
216 | addr = (unsigned long) ptr; | ||
217 | shift = (3 ^ (addr & 3)) << 3; | ||
218 | addr ^= addr & 3; | ||
219 | asm volatile( | ||
220 | " l %0,%2\n" | ||
221 | "0: nr %0,%5\n" | ||
222 | " lr %1,%0\n" | ||
223 | " or %0,%3\n" | ||
224 | " or %1,%4\n" | ||
225 | " cs %0,%1,%2\n" | ||
226 | " jnl 1f\n" | ||
227 | " xr %1,%0\n" | ||
228 | " nr %1,%5\n" | ||
229 | " jnz 0b\n" | ||
230 | "1:" | ||
231 | : "=&d" (prev), "=&d" (tmp), "=Q" (*(int *) ptr) | ||
232 | : "d" (old << shift), "d" (new << shift), | ||
233 | "d" (~(255 << shift)), "Q" (*(int *) ptr) | ||
234 | : "memory", "cc"); | ||
235 | return prev >> shift; | ||
236 | case 2: | ||
237 | addr = (unsigned long) ptr; | ||
238 | shift = (2 ^ (addr & 2)) << 3; | ||
239 | addr ^= addr & 2; | ||
240 | asm volatile( | ||
241 | " l %0,%2\n" | ||
242 | "0: nr %0,%5\n" | ||
243 | " lr %1,%0\n" | ||
244 | " or %0,%3\n" | ||
245 | " or %1,%4\n" | ||
246 | " cs %0,%1,%2\n" | ||
247 | " jnl 1f\n" | ||
248 | " xr %1,%0\n" | ||
249 | " nr %1,%5\n" | ||
250 | " jnz 0b\n" | ||
251 | "1:" | ||
252 | : "=&d" (prev), "=&d" (tmp), "=Q" (*(int *) ptr) | ||
253 | : "d" (old << shift), "d" (new << shift), | ||
254 | "d" (~(65535 << shift)), "Q" (*(int *) ptr) | ||
255 | : "memory", "cc"); | ||
256 | return prev >> shift; | ||
257 | case 4: | ||
258 | asm volatile( | ||
259 | " cs %0,%3,%1\n" | ||
260 | : "=&d" (prev), "=Q" (*(int *) ptr) | ||
261 | : "0" (old), "d" (new), "Q" (*(int *) ptr) | ||
262 | : "memory", "cc"); | ||
263 | return prev; | ||
264 | #ifdef __s390x__ | ||
265 | case 8: | ||
266 | asm volatile( | ||
267 | " csg %0,%3,%1\n" | ||
268 | : "=&d" (prev), "=Q" (*(long *) ptr) | ||
269 | : "0" (old), "d" (new), "Q" (*(long *) ptr) | ||
270 | : "memory", "cc"); | ||
271 | return prev; | ||
272 | #endif /* __s390x__ */ | ||
273 | } | ||
274 | __cmpxchg_called_with_bad_pointer(); | ||
275 | return old; | ||
276 | } | ||
277 | |||
278 | /* | 124 | /* |
279 | * Force strict CPU ordering. | 125 | * Force strict CPU ordering. |
280 | * And yes, this is required on UP too when we're talking | 126 | * And yes, this is required on UP too when we're talking |
@@ -353,46 +199,6 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) | |||
353 | __ctl_load(__dummy, cr, cr); \ | 199 | __ctl_load(__dummy, cr, cr); \ |
354 | }) | 200 | }) |
355 | 201 | ||
356 | #include <linux/irqflags.h> | ||
357 | |||
358 | #include <asm-generic/cmpxchg-local.h> | ||
359 | |||
360 | static inline unsigned long __cmpxchg_local(volatile void *ptr, | ||
361 | unsigned long old, | ||
362 | unsigned long new, int size) | ||
363 | { | ||
364 | switch (size) { | ||
365 | case 1: | ||
366 | case 2: | ||
367 | case 4: | ||
368 | #ifdef __s390x__ | ||
369 | case 8: | ||
370 | #endif | ||
371 | return __cmpxchg(ptr, old, new, size); | ||
372 | default: | ||
373 | return __cmpxchg_local_generic(ptr, old, new, size); | ||
374 | } | ||
375 | |||
376 | return old; | ||
377 | } | ||
378 | |||
379 | /* | ||
380 | * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make | ||
381 | * them available. | ||
382 | */ | ||
383 | #define cmpxchg_local(ptr, o, n) \ | ||
384 | ((__typeof__(*(ptr)))__cmpxchg_local((ptr), (unsigned long)(o), \ | ||
385 | (unsigned long)(n), sizeof(*(ptr)))) | ||
386 | #ifdef __s390x__ | ||
387 | #define cmpxchg64_local(ptr, o, n) \ | ||
388 | ({ \ | ||
389 | BUILD_BUG_ON(sizeof(*(ptr)) != 8); \ | ||
390 | cmpxchg_local((ptr), (o), (n)); \ | ||
391 | }) | ||
392 | #else | ||
393 | #define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n)) | ||
394 | #endif | ||
395 | |||
396 | /* | 202 | /* |
397 | * Use to set psw mask except for the first byte which | 203 | * Use to set psw mask except for the first byte which |
398 | * won't be changed by this function. | 204 | * won't be changed by this function. |
diff --git a/arch/s390/include/asm/unistd.h b/arch/s390/include/asm/unistd.h index 1049ef27c15e..e82152572377 100644 --- a/arch/s390/include/asm/unistd.h +++ b/arch/s390/include/asm/unistd.h | |||
@@ -272,7 +272,11 @@ | |||
272 | #define __NR_fanotify_init 332 | 272 | #define __NR_fanotify_init 332 |
273 | #define __NR_fanotify_mark 333 | 273 | #define __NR_fanotify_mark 333 |
274 | #define __NR_prlimit64 334 | 274 | #define __NR_prlimit64 334 |
275 | #define NR_syscalls 335 | 275 | #define __NR_name_to_handle_at 335 |
276 | #define __NR_open_by_handle_at 336 | ||
277 | #define __NR_clock_adjtime 337 | ||
278 | #define __NR_syncfs 338 | ||
279 | #define NR_syscalls 339 | ||
276 | 280 | ||
277 | /* | 281 | /* |
278 | * There are some system calls that are not present on 64 bit, some | 282 | * There are some system calls that are not present on 64 bit, some |
diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index 8e60fb23b90d..1dc96ea08fa8 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S | |||
@@ -1877,3 +1877,30 @@ sys_prlimit64_wrapper: | |||
1877 | llgtr %r4,%r4 # const struct rlimit64 __user * | 1877 | llgtr %r4,%r4 # const struct rlimit64 __user * |
1878 | llgtr %r5,%r5 # struct rlimit64 __user * | 1878 | llgtr %r5,%r5 # struct rlimit64 __user * |
1879 | jg sys_prlimit64 # branch to system call | 1879 | jg sys_prlimit64 # branch to system call |
1880 | |||
1881 | .globl sys_name_to_handle_at_wrapper | ||
1882 | sys_name_to_handle_at_wrapper: | ||
1883 | lgfr %r2,%r2 # int | ||
1884 | llgtr %r3,%r3 # const char __user * | ||
1885 | llgtr %r4,%r4 # struct file_handle __user * | ||
1886 | llgtr %r5,%r5 # int __user * | ||
1887 | lgfr %r6,%r6 # int | ||
1888 | jg sys_name_to_handle_at | ||
1889 | |||
1890 | .globl compat_sys_open_by_handle_at_wrapper | ||
1891 | compat_sys_open_by_handle_at_wrapper: | ||
1892 | lgfr %r2,%r2 # int | ||
1893 | llgtr %r3,%r3 # struct file_handle __user * | ||
1894 | lgfr %r4,%r4 # int | ||
1895 | jg compat_sys_open_by_handle_at | ||
1896 | |||
1897 | .globl compat_sys_clock_adjtime_wrapper | ||
1898 | compat_sys_clock_adjtime_wrapper: | ||
1899 | lgfr %r2,%r2 # clockid_t (int) | ||
1900 | llgtr %r3,%r3 # struct compat_timex __user * | ||
1901 | jg compat_sys_clock_adjtime | ||
1902 | |||
1903 | .globl sys_syncfs_wrapper | ||
1904 | sys_syncfs_wrapper: | ||
1905 | lgfr %r2,%r2 # int | ||
1906 | jg sys_syncfs | ||
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index 3b7e7dddc324..068f8465c4ee 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c | |||
@@ -94,6 +94,7 @@ static noinline __init void create_kernel_nss(void) | |||
94 | unsigned int sinitrd_pfn, einitrd_pfn; | 94 | unsigned int sinitrd_pfn, einitrd_pfn; |
95 | #endif | 95 | #endif |
96 | int response; | 96 | int response; |
97 | int hlen; | ||
97 | size_t len; | 98 | size_t len; |
98 | char *savesys_ptr; | 99 | char *savesys_ptr; |
99 | char defsys_cmd[DEFSYS_CMD_SIZE]; | 100 | char defsys_cmd[DEFSYS_CMD_SIZE]; |
@@ -124,24 +125,27 @@ static noinline __init void create_kernel_nss(void) | |||
124 | end_pfn = PFN_UP(__pa(&_end)); | 125 | end_pfn = PFN_UP(__pa(&_end)); |
125 | min_size = end_pfn << 2; | 126 | min_size = end_pfn << 2; |
126 | 127 | ||
127 | sprintf(defsys_cmd, "DEFSYS %s 00000-%.5X EW %.5X-%.5X SR %.5X-%.5X", | 128 | hlen = snprintf(defsys_cmd, DEFSYS_CMD_SIZE, |
128 | kernel_nss_name, stext_pfn - 1, stext_pfn, eshared_pfn - 1, | 129 | "DEFSYS %s 00000-%.5X EW %.5X-%.5X SR %.5X-%.5X", |
129 | eshared_pfn, end_pfn); | 130 | kernel_nss_name, stext_pfn - 1, stext_pfn, |
131 | eshared_pfn - 1, eshared_pfn, end_pfn); | ||
130 | 132 | ||
131 | #ifdef CONFIG_BLK_DEV_INITRD | 133 | #ifdef CONFIG_BLK_DEV_INITRD |
132 | if (INITRD_START && INITRD_SIZE) { | 134 | if (INITRD_START && INITRD_SIZE) { |
133 | sinitrd_pfn = PFN_DOWN(__pa(INITRD_START)); | 135 | sinitrd_pfn = PFN_DOWN(__pa(INITRD_START)); |
134 | einitrd_pfn = PFN_UP(__pa(INITRD_START + INITRD_SIZE)); | 136 | einitrd_pfn = PFN_UP(__pa(INITRD_START + INITRD_SIZE)); |
135 | min_size = einitrd_pfn << 2; | 137 | min_size = einitrd_pfn << 2; |
136 | sprintf(defsys_cmd, "%s EW %.5X-%.5X", defsys_cmd, | 138 | hlen += snprintf(defsys_cmd + hlen, DEFSYS_CMD_SIZE - hlen, |
137 | sinitrd_pfn, einitrd_pfn); | 139 | " EW %.5X-%.5X", sinitrd_pfn, einitrd_pfn); |
138 | } | 140 | } |
139 | #endif | 141 | #endif |
140 | 142 | ||
141 | sprintf(defsys_cmd, "%s EW MINSIZE=%.7iK PARMREGS=0-13", | 143 | snprintf(defsys_cmd + hlen, DEFSYS_CMD_SIZE - hlen, |
142 | defsys_cmd, min_size); | 144 | " EW MINSIZE=%.7iK PARMREGS=0-13", min_size); |
143 | sprintf(savesys_cmd, "SAVESYS %s \n IPL %s", | 145 | defsys_cmd[DEFSYS_CMD_SIZE - 1] = '\0'; |
144 | kernel_nss_name, kernel_nss_name); | 146 | snprintf(savesys_cmd, SAVESYS_CMD_SIZE, "SAVESYS %s \n IPL %s", |
147 | kernel_nss_name, kernel_nss_name); | ||
148 | savesys_cmd[SAVESYS_CMD_SIZE - 1] = '\0'; | ||
145 | 149 | ||
146 | __cpcmd(defsys_cmd, NULL, 0, &response); | 150 | __cpcmd(defsys_cmd, NULL, 0, &response); |
147 | 151 | ||
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 6f6350826c81..ed183c2c6168 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c | |||
@@ -102,16 +102,6 @@ EXPORT_SYMBOL(lowcore_ptr); | |||
102 | 102 | ||
103 | #include <asm/setup.h> | 103 | #include <asm/setup.h> |
104 | 104 | ||
105 | static struct resource code_resource = { | ||
106 | .name = "Kernel code", | ||
107 | .flags = IORESOURCE_BUSY | IORESOURCE_MEM, | ||
108 | }; | ||
109 | |||
110 | static struct resource data_resource = { | ||
111 | .name = "Kernel data", | ||
112 | .flags = IORESOURCE_BUSY | IORESOURCE_MEM, | ||
113 | }; | ||
114 | |||
115 | /* | 105 | /* |
116 | * condev= and conmode= setup parameter. | 106 | * condev= and conmode= setup parameter. |
117 | */ | 107 | */ |
@@ -436,21 +426,43 @@ setup_lowcore(void) | |||
436 | lowcore_ptr[0] = lc; | 426 | lowcore_ptr[0] = lc; |
437 | } | 427 | } |
438 | 428 | ||
439 | static void __init | 429 | static struct resource code_resource = { |
440 | setup_resources(void) | 430 | .name = "Kernel code", |
431 | .flags = IORESOURCE_BUSY | IORESOURCE_MEM, | ||
432 | }; | ||
433 | |||
434 | static struct resource data_resource = { | ||
435 | .name = "Kernel data", | ||
436 | .flags = IORESOURCE_BUSY | IORESOURCE_MEM, | ||
437 | }; | ||
438 | |||
439 | static struct resource bss_resource = { | ||
440 | .name = "Kernel bss", | ||
441 | .flags = IORESOURCE_BUSY | IORESOURCE_MEM, | ||
442 | }; | ||
443 | |||
444 | static struct resource __initdata *standard_resources[] = { | ||
445 | &code_resource, | ||
446 | &data_resource, | ||
447 | &bss_resource, | ||
448 | }; | ||
449 | |||
450 | static void __init setup_resources(void) | ||
441 | { | 451 | { |
442 | struct resource *res, *sub_res; | 452 | struct resource *res, *std_res, *sub_res; |
443 | int i; | 453 | int i, j; |
444 | 454 | ||
445 | code_resource.start = (unsigned long) &_text; | 455 | code_resource.start = (unsigned long) &_text; |
446 | code_resource.end = (unsigned long) &_etext - 1; | 456 | code_resource.end = (unsigned long) &_etext - 1; |
447 | data_resource.start = (unsigned long) &_etext; | 457 | data_resource.start = (unsigned long) &_etext; |
448 | data_resource.end = (unsigned long) &_edata - 1; | 458 | data_resource.end = (unsigned long) &_edata - 1; |
459 | bss_resource.start = (unsigned long) &__bss_start; | ||
460 | bss_resource.end = (unsigned long) &__bss_stop - 1; | ||
449 | 461 | ||
450 | for (i = 0; i < MEMORY_CHUNKS; i++) { | 462 | for (i = 0; i < MEMORY_CHUNKS; i++) { |
451 | if (!memory_chunk[i].size) | 463 | if (!memory_chunk[i].size) |
452 | continue; | 464 | continue; |
453 | res = alloc_bootmem_low(sizeof(struct resource)); | 465 | res = alloc_bootmem_low(sizeof(*res)); |
454 | res->flags = IORESOURCE_BUSY | IORESOURCE_MEM; | 466 | res->flags = IORESOURCE_BUSY | IORESOURCE_MEM; |
455 | switch (memory_chunk[i].type) { | 467 | switch (memory_chunk[i].type) { |
456 | case CHUNK_READ_WRITE: | 468 | case CHUNK_READ_WRITE: |
@@ -464,40 +476,24 @@ setup_resources(void) | |||
464 | res->name = "reserved"; | 476 | res->name = "reserved"; |
465 | } | 477 | } |
466 | res->start = memory_chunk[i].addr; | 478 | res->start = memory_chunk[i].addr; |
467 | res->end = memory_chunk[i].addr + memory_chunk[i].size - 1; | 479 | res->end = res->start + memory_chunk[i].size - 1; |
468 | request_resource(&iomem_resource, res); | 480 | request_resource(&iomem_resource, res); |
469 | 481 | ||
470 | if (code_resource.start >= res->start && | 482 | for (j = 0; j < ARRAY_SIZE(standard_resources); j++) { |
471 | code_resource.start <= res->end && | 483 | std_res = standard_resources[j]; |
472 | code_resource.end > res->end) { | 484 | if (std_res->start < res->start || |
473 | sub_res = alloc_bootmem_low(sizeof(struct resource)); | 485 | std_res->start > res->end) |
474 | memcpy(sub_res, &code_resource, | 486 | continue; |
475 | sizeof(struct resource)); | 487 | if (std_res->end > res->end) { |
476 | sub_res->end = res->end; | 488 | sub_res = alloc_bootmem_low(sizeof(*sub_res)); |
477 | code_resource.start = res->end + 1; | 489 | *sub_res = *std_res; |
478 | request_resource(res, sub_res); | 490 | sub_res->end = res->end; |
479 | } | 491 | std_res->start = res->end + 1; |
480 | 492 | request_resource(res, sub_res); | |
481 | if (code_resource.start >= res->start && | 493 | } else { |
482 | code_resource.start <= res->end && | 494 | request_resource(res, std_res); |
483 | code_resource.end <= res->end) | 495 | } |
484 | request_resource(res, &code_resource); | ||
485 | |||
486 | if (data_resource.start >= res->start && | ||
487 | data_resource.start <= res->end && | ||
488 | data_resource.end > res->end) { | ||
489 | sub_res = alloc_bootmem_low(sizeof(struct resource)); | ||
490 | memcpy(sub_res, &data_resource, | ||
491 | sizeof(struct resource)); | ||
492 | sub_res->end = res->end; | ||
493 | data_resource.start = res->end + 1; | ||
494 | request_resource(res, sub_res); | ||
495 | } | 496 | } |
496 | |||
497 | if (data_resource.start >= res->start && | ||
498 | data_resource.start <= res->end && | ||
499 | data_resource.end <= res->end) | ||
500 | request_resource(res, &data_resource); | ||
501 | } | 497 | } |
502 | } | 498 | } |
503 | 499 | ||
diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S index a8fee1b14395..9c65fd4ddce0 100644 --- a/arch/s390/kernel/syscalls.S +++ b/arch/s390/kernel/syscalls.S | |||
@@ -343,3 +343,7 @@ SYSCALL(sys_perf_event_open,sys_perf_event_open,sys_perf_event_open_wrapper) | |||
343 | SYSCALL(sys_fanotify_init,sys_fanotify_init,sys_fanotify_init_wrapper) | 343 | SYSCALL(sys_fanotify_init,sys_fanotify_init,sys_fanotify_init_wrapper) |
344 | SYSCALL(sys_fanotify_mark,sys_fanotify_mark,sys_fanotify_mark_wrapper) | 344 | SYSCALL(sys_fanotify_mark,sys_fanotify_mark,sys_fanotify_mark_wrapper) |
345 | SYSCALL(sys_prlimit64,sys_prlimit64,sys_prlimit64_wrapper) | 345 | SYSCALL(sys_prlimit64,sys_prlimit64,sys_prlimit64_wrapper) |
346 | SYSCALL(sys_name_to_handle_at,sys_name_to_handle_at,sys_name_to_handle_at_wrapper) /* 335 */ | ||
347 | SYSCALL(sys_open_by_handle_at,sys_open_by_handle_at,compat_sys_open_by_handle_at_wrapper) | ||
348 | SYSCALL(sys_clock_adjtime,sys_clock_adjtime,compat_sys_clock_adjtime_wrapper) | ||
349 | SYSCALL(sys_syncfs,sys_syncfs,sys_syncfs_wrapper) | ||
diff --git a/arch/s390/oprofile/Makefile b/arch/s390/oprofile/Makefile index d698cddcfbdd..524c4b615821 100644 --- a/arch/s390/oprofile/Makefile +++ b/arch/s390/oprofile/Makefile | |||
@@ -6,4 +6,5 @@ DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \ | |||
6 | oprofilefs.o oprofile_stats.o \ | 6 | oprofilefs.o oprofile_stats.o \ |
7 | timer_int.o ) | 7 | timer_int.o ) |
8 | 8 | ||
9 | oprofile-y := $(DRIVER_OBJS) init.o backtrace.o hwsampler.o | 9 | oprofile-y := $(DRIVER_OBJS) init.o backtrace.o |
10 | oprofile-$(CONFIG_64BIT) += hwsampler.o | ||
diff --git a/arch/s390/oprofile/init.c b/arch/s390/oprofile/init.c index 16c76def4a9d..c63d7e58352b 100644 --- a/arch/s390/oprofile/init.c +++ b/arch/s390/oprofile/init.c | |||
@@ -18,6 +18,11 @@ | |||
18 | #include <linux/fs.h> | 18 | #include <linux/fs.h> |
19 | 19 | ||
20 | #include "../../../drivers/oprofile/oprof.h" | 20 | #include "../../../drivers/oprofile/oprof.h" |
21 | |||
22 | extern void s390_backtrace(struct pt_regs * const regs, unsigned int depth); | ||
23 | |||
24 | #ifdef CONFIG_64BIT | ||
25 | |||
21 | #include "hwsampler.h" | 26 | #include "hwsampler.h" |
22 | 27 | ||
23 | #define DEFAULT_INTERVAL 4096 | 28 | #define DEFAULT_INTERVAL 4096 |
@@ -37,8 +42,6 @@ static int hwsampler_running; /* start_mutex must be held to change */ | |||
37 | 42 | ||
38 | static struct oprofile_operations timer_ops; | 43 | static struct oprofile_operations timer_ops; |
39 | 44 | ||
40 | extern void s390_backtrace(struct pt_regs * const regs, unsigned int depth); | ||
41 | |||
42 | static int oprofile_hwsampler_start(void) | 45 | static int oprofile_hwsampler_start(void) |
43 | { | 46 | { |
44 | int retval; | 47 | int retval; |
@@ -172,14 +175,22 @@ static void oprofile_hwsampler_exit(void) | |||
172 | hwsampler_shutdown(); | 175 | hwsampler_shutdown(); |
173 | } | 176 | } |
174 | 177 | ||
178 | #endif /* CONFIG_64BIT */ | ||
179 | |||
175 | int __init oprofile_arch_init(struct oprofile_operations *ops) | 180 | int __init oprofile_arch_init(struct oprofile_operations *ops) |
176 | { | 181 | { |
177 | ops->backtrace = s390_backtrace; | 182 | ops->backtrace = s390_backtrace; |
178 | 183 | ||
184 | #ifdef CONFIG_64BIT | ||
179 | return oprofile_hwsampler_init(ops); | 185 | return oprofile_hwsampler_init(ops); |
186 | #else | ||
187 | return -ENODEV; | ||
188 | #endif | ||
180 | } | 189 | } |
181 | 190 | ||
182 | void oprofile_arch_exit(void) | 191 | void oprofile_arch_exit(void) |
183 | { | 192 | { |
193 | #ifdef CONFIG_64BIT | ||
184 | oprofile_hwsampler_exit(); | 194 | oprofile_hwsampler_exit(); |
195 | #endif | ||
185 | } | 196 | } |