aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-01-09 11:11:13 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-01-09 11:11:13 -0500
commit72f318897e50c29b91efd1ed24515a93c138a2ba (patch)
tree7e7ef8138d5afacd1be4655e4458dc4cee432d1e /arch/s390
parenta0e86bd4252519321b0d102dc4ed90557aa7bee9 (diff)
parent2fa1d4fce599809e6bd7d95756709a5faef30710 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: (31 commits) [S390] disassembler: mark exception causing instructions [S390] Enable exception traces by default [S390] return address of compat signals [S390] sysctl: get rid of dead declaration [S390] dasd: fix fixpoint divide exception in define_extent [S390] dasd: add sanity check to detect path connection error [S390] qdio: fix kernel panic for zfcp 31-bit [S390] Add s390x description to Documentation/kdump/kdump.txt [S390] Add VMCOREINFO_SYMBOL(high_memory) to vmcoreinfo [S390] dasd: fix expiration handling for recovery requests [S390] outstanding interrupts vs. smp_send_stop [S390] ipc: call generic sys_ipc demultiplexer [S390] zcrypt: Fix error return codes. [S390] zcrypt: Rework length parameter checking. [S390] cleanup trap handling [S390] Remove Kerntypes leftovers [S390] topology: increase poll frequency if change is anticipated [S390] entry[64].S improvements [S390] make arch/s390 subdirectories depend on config option [S390] kvm: move cmf host id constant out of lowcore ... Fix up conflicts in arch/s390/kernel/{smp.c,topology.c} due to the sysdev removal clashing with "topology: get rid of ifdefs" which moved some of that code around.
Diffstat (limited to 'arch/s390')
-rw-r--r--arch/s390/Kbuild13
-rw-r--r--arch/s390/Kconfig11
-rw-r--r--arch/s390/Makefile1
-rw-r--r--arch/s390/boot/Makefile2
-rw-r--r--arch/s390/include/asm/kdebug.h2
-rw-r--r--arch/s390/include/asm/lowcore.h142
-rw-r--r--arch/s390/include/asm/pgtable.h23
-rw-r--r--arch/s390/include/asm/processor.h2
-rw-r--r--arch/s390/include/asm/ptrace.h3
-rw-r--r--arch/s390/include/asm/qdio.h5
-rw-r--r--arch/s390/include/asm/sigp.h1
-rw-r--r--arch/s390/include/asm/smp.h1
-rw-r--r--arch/s390/include/asm/sparsemem.h4
-rw-r--r--arch/s390/include/asm/syscall.h2
-rw-r--r--arch/s390/include/asm/system.h2
-rw-r--r--arch/s390/include/asm/topology.h40
-rw-r--r--arch/s390/include/asm/unistd.h1
-rw-r--r--arch/s390/kernel/Makefile3
-rw-r--r--arch/s390/kernel/asm-offsets.c8
-rw-r--r--arch/s390/kernel/base.S16
-rw-r--r--arch/s390/kernel/compat_linux.c3
-rw-r--r--arch/s390/kernel/compat_signal.c12
-rw-r--r--arch/s390/kernel/dis.c9
-rw-r--r--arch/s390/kernel/early.c20
-rw-r--r--arch/s390/kernel/entry.S1103
-rw-r--r--arch/s390/kernel/entry.h10
-rw-r--r--arch/s390/kernel/entry64.S976
-rw-r--r--arch/s390/kernel/head.S4
-rw-r--r--arch/s390/kernel/machine_kexec.c1
-rw-r--r--arch/s390/kernel/mem_detect.c122
-rw-r--r--arch/s390/kernel/reipl64.S4
-rw-r--r--arch/s390/kernel/setup.c69
-rw-r--r--arch/s390/kernel/signal.c20
-rw-r--r--arch/s390/kernel/smp.c173
-rw-r--r--arch/s390/kernel/sys_s390.c76
-rw-r--r--arch/s390/kernel/topology.c275
-rw-r--r--arch/s390/kernel/traps.c170
-rw-r--r--arch/s390/mm/fault.c107
-rw-r--r--arch/s390/mm/init.c16
-rw-r--r--arch/s390/mm/pgtable.c14
40 files changed, 1626 insertions, 1840 deletions
diff --git a/arch/s390/Kbuild b/arch/s390/Kbuild
index ae4b01060edd..9858476fa0fe 100644
--- a/arch/s390/Kbuild
+++ b/arch/s390/Kbuild
@@ -1,6 +1,7 @@
1obj-y += kernel/ 1obj-y += kernel/
2obj-y += mm/ 2obj-y += mm/
3obj-y += crypto/ 3obj-$(CONFIG_KVM) += kvm/
4obj-y += appldata/ 4obj-$(CONFIG_CRYPTO_HW) += crypto/
5obj-y += hypfs/ 5obj-$(CONFIG_S390_HYPFS_FS) += hypfs/
6obj-y += kvm/ 6obj-$(CONFIG_APPLDATA_BASE) += appldata/
7obj-$(CONFIG_MATHEMU) += math-emu/
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 28d183c42751..d1727584230a 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -193,18 +193,13 @@ config HOTPLUG_CPU
193 Say N if you want to disable CPU hotplug. 193 Say N if you want to disable CPU hotplug.
194 194
195config SCHED_MC 195config SCHED_MC
196 def_bool y 196 def_bool n
197 prompt "Multi-core scheduler support"
198 depends on SMP
199 help
200 Multi-core scheduler support improves the CPU scheduler's decision
201 making when dealing with multi-core CPU chips at a cost of slightly
202 increased overhead in some places.
203 197
204config SCHED_BOOK 198config SCHED_BOOK
205 def_bool y 199 def_bool y
206 prompt "Book scheduler support" 200 prompt "Book scheduler support"
207 depends on SMP && SCHED_MC 201 depends on SMP
202 select SCHED_MC
208 help 203 help
209 Book scheduler support improves the CPU scheduler's decision making 204 Book scheduler support improves the CPU scheduler's decision making
210 when dealing with machines that have several books. 205 when dealing with machines that have several books.
diff --git a/arch/s390/Makefile b/arch/s390/Makefile
index 27a0b5df5ead..e9f353341693 100644
--- a/arch/s390/Makefile
+++ b/arch/s390/Makefile
@@ -99,7 +99,6 @@ core-y += arch/s390/
99 99
100libs-y += arch/s390/lib/ 100libs-y += arch/s390/lib/
101drivers-y += drivers/s390/ 101drivers-y += drivers/s390/
102drivers-$(CONFIG_MATHEMU) += arch/s390/math-emu/
103 102
104# must be linked after kernel 103# must be linked after kernel
105drivers-$(CONFIG_OPROFILE) += arch/s390/oprofile/ 104drivers-$(CONFIG_OPROFILE) += arch/s390/oprofile/
diff --git a/arch/s390/boot/Makefile b/arch/s390/boot/Makefile
index 635d677d3281..f2737a005afc 100644
--- a/arch/s390/boot/Makefile
+++ b/arch/s390/boot/Makefile
@@ -23,4 +23,4 @@ $(obj)/compressed/vmlinux: FORCE
23 23
24install: $(CONFIGURE) $(obj)/image 24install: $(CONFIGURE) $(obj)/image
25 sh -x $(srctree)/$(obj)/install.sh $(KERNELRELEASE) $(obj)/image \ 25 sh -x $(srctree)/$(obj)/install.sh $(KERNELRELEASE) $(obj)/image \
26 System.map Kerntypes "$(INSTALL_PATH)" 26 System.map "$(INSTALL_PATH)"
diff --git a/arch/s390/include/asm/kdebug.h b/arch/s390/include/asm/kdebug.h
index 40db27cd6e60..5c1abd47612a 100644
--- a/arch/s390/include/asm/kdebug.h
+++ b/arch/s390/include/asm/kdebug.h
@@ -22,6 +22,6 @@ enum die_val {
22 DIE_NMI_IPI, 22 DIE_NMI_IPI,
23}; 23};
24 24
25extern void die(const char *, struct pt_regs *, long); 25extern void die(struct pt_regs *, const char *);
26 26
27#endif 27#endif
diff --git a/arch/s390/include/asm/lowcore.h b/arch/s390/include/asm/lowcore.h
index 9e13c7d56cc1..707f2306725b 100644
--- a/arch/s390/include/asm/lowcore.h
+++ b/arch/s390/include/asm/lowcore.h
@@ -97,47 +97,52 @@ struct _lowcore {
97 __u32 gpregs_save_area[16]; /* 0x0180 */ 97 __u32 gpregs_save_area[16]; /* 0x0180 */
98 __u32 cregs_save_area[16]; /* 0x01c0 */ 98 __u32 cregs_save_area[16]; /* 0x01c0 */
99 99
100 /* Save areas. */
101 __u32 save_area_sync[8]; /* 0x0200 */
102 __u32 save_area_async[8]; /* 0x0220 */
103 __u32 save_area_restart[1]; /* 0x0240 */
104 __u8 pad_0x0244[0x0248-0x0244]; /* 0x0244 */
105
100 /* Return psws. */ 106 /* Return psws. */
101 __u32 save_area[16]; /* 0x0200 */ 107 psw_t return_psw; /* 0x0248 */
102 psw_t return_psw; /* 0x0240 */ 108 psw_t return_mcck_psw; /* 0x0250 */
103 psw_t return_mcck_psw; /* 0x0248 */
104 109
105 /* CPU time accounting values */ 110 /* CPU time accounting values */
106 __u64 sync_enter_timer; /* 0x0250 */ 111 __u64 sync_enter_timer; /* 0x0258 */
107 __u64 async_enter_timer; /* 0x0258 */ 112 __u64 async_enter_timer; /* 0x0260 */
108 __u64 mcck_enter_timer; /* 0x0260 */ 113 __u64 mcck_enter_timer; /* 0x0268 */
109 __u64 exit_timer; /* 0x0268 */ 114 __u64 exit_timer; /* 0x0270 */
110 __u64 user_timer; /* 0x0270 */ 115 __u64 user_timer; /* 0x0278 */
111 __u64 system_timer; /* 0x0278 */ 116 __u64 system_timer; /* 0x0280 */
112 __u64 steal_timer; /* 0x0280 */ 117 __u64 steal_timer; /* 0x0288 */
113 __u64 last_update_timer; /* 0x0288 */ 118 __u64 last_update_timer; /* 0x0290 */
114 __u64 last_update_clock; /* 0x0290 */ 119 __u64 last_update_clock; /* 0x0298 */
115 120
116 /* Current process. */ 121 /* Current process. */
117 __u32 current_task; /* 0x0298 */ 122 __u32 current_task; /* 0x02a0 */
118 __u32 thread_info; /* 0x029c */ 123 __u32 thread_info; /* 0x02a4 */
119 __u32 kernel_stack; /* 0x02a0 */ 124 __u32 kernel_stack; /* 0x02a8 */
120 125
121 /* Interrupt and panic stack. */ 126 /* Interrupt and panic stack. */
122 __u32 async_stack; /* 0x02a4 */ 127 __u32 async_stack; /* 0x02ac */
123 __u32 panic_stack; /* 0x02a8 */ 128 __u32 panic_stack; /* 0x02b0 */
124 129
125 /* Address space pointer. */ 130 /* Address space pointer. */
126 __u32 kernel_asce; /* 0x02ac */ 131 __u32 kernel_asce; /* 0x02b4 */
127 __u32 user_asce; /* 0x02b0 */ 132 __u32 user_asce; /* 0x02b8 */
128 __u32 current_pid; /* 0x02b4 */ 133 __u32 current_pid; /* 0x02bc */
129 134
130 /* SMP info area */ 135 /* SMP info area */
131 __u32 cpu_nr; /* 0x02b8 */ 136 __u32 cpu_nr; /* 0x02c0 */
132 __u32 softirq_pending; /* 0x02bc */ 137 __u32 softirq_pending; /* 0x02c4 */
133 __u32 percpu_offset; /* 0x02c0 */ 138 __u32 percpu_offset; /* 0x02c8 */
134 __u32 ext_call_fast; /* 0x02c4 */ 139 __u32 ext_call_fast; /* 0x02cc */
135 __u64 int_clock; /* 0x02c8 */ 140 __u64 int_clock; /* 0x02d0 */
136 __u64 mcck_clock; /* 0x02d0 */ 141 __u64 mcck_clock; /* 0x02d8 */
137 __u64 clock_comparator; /* 0x02d8 */ 142 __u64 clock_comparator; /* 0x02e0 */
138 __u32 machine_flags; /* 0x02e0 */ 143 __u32 machine_flags; /* 0x02e8 */
139 __u32 ftrace_func; /* 0x02e4 */ 144 __u32 ftrace_func; /* 0x02ec */
140 __u8 pad_0x02e8[0x0300-0x02e8]; /* 0x02e8 */ 145 __u8 pad_0x02f8[0x0300-0x02f0]; /* 0x02f0 */
141 146
142 /* Interrupt response block */ 147 /* Interrupt response block */
143 __u8 irb[64]; /* 0x0300 */ 148 __u8 irb[64]; /* 0x0300 */
@@ -229,57 +234,62 @@ struct _lowcore {
229 psw_t mcck_new_psw; /* 0x01e0 */ 234 psw_t mcck_new_psw; /* 0x01e0 */
230 psw_t io_new_psw; /* 0x01f0 */ 235 psw_t io_new_psw; /* 0x01f0 */
231 236
232 /* Entry/exit save area & return psws. */ 237 /* Save areas. */
233 __u64 save_area[16]; /* 0x0200 */ 238 __u64 save_area_sync[8]; /* 0x0200 */
234 psw_t return_psw; /* 0x0280 */ 239 __u64 save_area_async[8]; /* 0x0240 */
235 psw_t return_mcck_psw; /* 0x0290 */ 240 __u64 save_area_restart[1]; /* 0x0280 */
241 __u8 pad_0x0288[0x0290-0x0288]; /* 0x0288 */
242
243 /* Return psws. */
244 psw_t return_psw; /* 0x0290 */
245 psw_t return_mcck_psw; /* 0x02a0 */
236 246
237 /* CPU accounting and timing values. */ 247 /* CPU accounting and timing values. */
238 __u64 sync_enter_timer; /* 0x02a0 */ 248 __u64 sync_enter_timer; /* 0x02b0 */
239 __u64 async_enter_timer; /* 0x02a8 */ 249 __u64 async_enter_timer; /* 0x02b8 */
240 __u64 mcck_enter_timer; /* 0x02b0 */ 250 __u64 mcck_enter_timer; /* 0x02c0 */
241 __u64 exit_timer; /* 0x02b8 */ 251 __u64 exit_timer; /* 0x02c8 */
242 __u64 user_timer; /* 0x02c0 */ 252 __u64 user_timer; /* 0x02d0 */
243 __u64 system_timer; /* 0x02c8 */ 253 __u64 system_timer; /* 0x02d8 */
244 __u64 steal_timer; /* 0x02d0 */ 254 __u64 steal_timer; /* 0x02e0 */
245 __u64 last_update_timer; /* 0x02d8 */ 255 __u64 last_update_timer; /* 0x02e8 */
246 __u64 last_update_clock; /* 0x02e0 */ 256 __u64 last_update_clock; /* 0x02f0 */
247 257
248 /* Current process. */ 258 /* Current process. */
249 __u64 current_task; /* 0x02e8 */ 259 __u64 current_task; /* 0x02f8 */
250 __u64 thread_info; /* 0x02f0 */ 260 __u64 thread_info; /* 0x0300 */
251 __u64 kernel_stack; /* 0x02f8 */ 261 __u64 kernel_stack; /* 0x0308 */
252 262
253 /* Interrupt and panic stack. */ 263 /* Interrupt and panic stack. */
254 __u64 async_stack; /* 0x0300 */ 264 __u64 async_stack; /* 0x0310 */
255 __u64 panic_stack; /* 0x0308 */ 265 __u64 panic_stack; /* 0x0318 */
256 266
257 /* Address space pointer. */ 267 /* Address space pointer. */
258 __u64 kernel_asce; /* 0x0310 */ 268 __u64 kernel_asce; /* 0x0320 */
259 __u64 user_asce; /* 0x0318 */ 269 __u64 user_asce; /* 0x0328 */
260 __u64 current_pid; /* 0x0320 */ 270 __u64 current_pid; /* 0x0330 */
261 271
262 /* SMP info area */ 272 /* SMP info area */
263 __u32 cpu_nr; /* 0x0328 */ 273 __u32 cpu_nr; /* 0x0338 */
264 __u32 softirq_pending; /* 0x032c */ 274 __u32 softirq_pending; /* 0x033c */
265 __u64 percpu_offset; /* 0x0330 */ 275 __u64 percpu_offset; /* 0x0340 */
266 __u64 ext_call_fast; /* 0x0338 */ 276 __u64 ext_call_fast; /* 0x0348 */
267 __u64 int_clock; /* 0x0340 */ 277 __u64 int_clock; /* 0x0350 */
268 __u64 mcck_clock; /* 0x0348 */ 278 __u64 mcck_clock; /* 0x0358 */
269 __u64 clock_comparator; /* 0x0350 */ 279 __u64 clock_comparator; /* 0x0360 */
270 __u64 vdso_per_cpu_data; /* 0x0358 */ 280 __u64 vdso_per_cpu_data; /* 0x0368 */
271 __u64 machine_flags; /* 0x0360 */ 281 __u64 machine_flags; /* 0x0370 */
272 __u64 ftrace_func; /* 0x0368 */ 282 __u64 ftrace_func; /* 0x0378 */
273 __u64 gmap; /* 0x0370 */ 283 __u64 gmap; /* 0x0380 */
274 __u64 cmf_hpp; /* 0x0378 */ 284 __u8 pad_0x0388[0x0400-0x0388]; /* 0x0388 */
275 285
276 /* Interrupt response block. */ 286 /* Interrupt response block. */
277 __u8 irb[64]; /* 0x0380 */ 287 __u8 irb[64]; /* 0x0400 */
278 288
279 /* Per cpu primary space access list */ 289 /* Per cpu primary space access list */
280 __u32 paste[16]; /* 0x03c0 */ 290 __u32 paste[16]; /* 0x0440 */
281 291
282 __u8 pad_0x0400[0x0e00-0x0400]; /* 0x0400 */ 292 __u8 pad_0x0480[0x0e00-0x0480]; /* 0x0480 */
283 293
284 /* 294 /*
285 * 0xe00 contains the address of the IPL Parameter Information 295 * 0xe00 contains the address of the IPL Parameter Information
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h
index 4f289ff0b7fe..011358c1b18e 100644
--- a/arch/s390/include/asm/pgtable.h
+++ b/arch/s390/include/asm/pgtable.h
@@ -128,28 +128,11 @@ static inline int is_zero_pfn(unsigned long pfn)
128 * effect, this also makes sure that 64 bit module code cannot be used 128 * effect, this also makes sure that 64 bit module code cannot be used
129 * as system call address. 129 * as system call address.
130 */ 130 */
131
132extern unsigned long VMALLOC_START; 131extern unsigned long VMALLOC_START;
132extern unsigned long VMALLOC_END;
133extern struct page *vmemmap;
133 134
134#ifndef __s390x__ 135#define VMEM_MAX_PHYS ((unsigned long) vmemmap)
135#define VMALLOC_SIZE (96UL << 20)
136#define VMALLOC_END 0x7e000000UL
137#define VMEM_MAP_END 0x80000000UL
138#else /* __s390x__ */
139#define VMALLOC_SIZE (128UL << 30)
140#define VMALLOC_END 0x3e000000000UL
141#define VMEM_MAP_END 0x40000000000UL
142#endif /* __s390x__ */
143
144/*
145 * VMEM_MAX_PHYS is the highest physical address that can be added to the 1:1
146 * mapping. This needs to be calculated at compile time since the size of the
147 * VMEM_MAP is static but the size of struct page can change.
148 */
149#define VMEM_MAX_PAGES ((VMEM_MAP_END - VMALLOC_END) / sizeof(struct page))
150#define VMEM_MAX_PFN min(VMALLOC_START >> PAGE_SHIFT, VMEM_MAX_PAGES)
151#define VMEM_MAX_PHYS ((VMEM_MAX_PFN << PAGE_SHIFT) & ~((16 << 20) - 1))
152#define vmemmap ((struct page *) VMALLOC_END)
153 136
154/* 137/*
155 * A 31 bit pagetable entry of S390 has following format: 138 * A 31 bit pagetable entry of S390 has following format:
diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h
index 5f33d37d032c..27272f6a14c2 100644
--- a/arch/s390/include/asm/processor.h
+++ b/arch/s390/include/asm/processor.h
@@ -80,8 +80,6 @@ struct thread_struct {
80 unsigned int acrs[NUM_ACRS]; 80 unsigned int acrs[NUM_ACRS];
81 unsigned long ksp; /* kernel stack pointer */ 81 unsigned long ksp; /* kernel stack pointer */
82 mm_segment_t mm_segment; 82 mm_segment_t mm_segment;
83 unsigned long prot_addr; /* address of protection-excep. */
84 unsigned int trap_no;
85 unsigned long gmap_addr; /* address of last gmap fault. */ 83 unsigned long gmap_addr; /* address of last gmap fault. */
86 struct per_regs per_user; /* User specified PER registers */ 84 struct per_regs per_user; /* User specified PER registers */
87 struct per_event per_event; /* Cause of the last PER trap */ 85 struct per_event per_event; /* Cause of the last PER trap */
diff --git a/arch/s390/include/asm/ptrace.h b/arch/s390/include/asm/ptrace.h
index a65846340d51..56da355678f4 100644
--- a/arch/s390/include/asm/ptrace.h
+++ b/arch/s390/include/asm/ptrace.h
@@ -324,7 +324,8 @@ struct pt_regs
324 psw_t psw; 324 psw_t psw;
325 unsigned long gprs[NUM_GPRS]; 325 unsigned long gprs[NUM_GPRS];
326 unsigned long orig_gpr2; 326 unsigned long orig_gpr2;
327 unsigned int svc_code; 327 unsigned int int_code;
328 unsigned long int_parm_long;
328}; 329};
329 330
330/* 331/*
diff --git a/arch/s390/include/asm/qdio.h b/arch/s390/include/asm/qdio.h
index e63d13dd3bf5..d75c8e78f7e3 100644
--- a/arch/s390/include/asm/qdio.h
+++ b/arch/s390/include/asm/qdio.h
@@ -352,7 +352,7 @@ typedef void qdio_handler_t(struct ccw_device *, unsigned int, int,
352 * @no_output_qs: number of output queues 352 * @no_output_qs: number of output queues
353 * @input_handler: handler to be called for input queues 353 * @input_handler: handler to be called for input queues
354 * @output_handler: handler to be called for output queues 354 * @output_handler: handler to be called for output queues
355 * @queue_start_poll: polling handlers (one per input queue or NULL) 355 * @queue_start_poll_array: polling handlers (one per input queue or NULL)
356 * @int_parm: interruption parameter 356 * @int_parm: interruption parameter
357 * @input_sbal_addr_array: address of no_input_qs * 128 pointers 357 * @input_sbal_addr_array: address of no_input_qs * 128 pointers
358 * @output_sbal_addr_array: address of no_output_qs * 128 pointers 358 * @output_sbal_addr_array: address of no_output_qs * 128 pointers
@@ -372,7 +372,8 @@ struct qdio_initialize {
372 unsigned int no_output_qs; 372 unsigned int no_output_qs;
373 qdio_handler_t *input_handler; 373 qdio_handler_t *input_handler;
374 qdio_handler_t *output_handler; 374 qdio_handler_t *output_handler;
375 void (**queue_start_poll) (struct ccw_device *, int, unsigned long); 375 void (**queue_start_poll_array) (struct ccw_device *, int,
376 unsigned long);
376 int scan_threshold; 377 int scan_threshold;
377 unsigned long int_parm; 378 unsigned long int_parm;
378 void **input_sbal_addr_array; 379 void **input_sbal_addr_array;
diff --git a/arch/s390/include/asm/sigp.h b/arch/s390/include/asm/sigp.h
index e3bffd4e2d66..7040b8567cd0 100644
--- a/arch/s390/include/asm/sigp.h
+++ b/arch/s390/include/asm/sigp.h
@@ -56,6 +56,7 @@ enum {
56 ec_schedule = 0, 56 ec_schedule = 0,
57 ec_call_function, 57 ec_call_function,
58 ec_call_function_single, 58 ec_call_function_single,
59 ec_stop_cpu,
59}; 60};
60 61
61/* 62/*
diff --git a/arch/s390/include/asm/smp.h b/arch/s390/include/asm/smp.h
index ab47a69fdf07..c32e9123b40c 100644
--- a/arch/s390/include/asm/smp.h
+++ b/arch/s390/include/asm/smp.h
@@ -23,7 +23,6 @@ extern void __cpu_die (unsigned int cpu);
23extern int __cpu_up (unsigned int cpu); 23extern int __cpu_up (unsigned int cpu);
24 24
25extern struct mutex smp_cpu_state_mutex; 25extern struct mutex smp_cpu_state_mutex;
26extern int smp_cpu_polarization[];
27 26
28extern void arch_send_call_function_single_ipi(int cpu); 27extern void arch_send_call_function_single_ipi(int cpu);
29extern void arch_send_call_function_ipi_mask(const struct cpumask *mask); 28extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
diff --git a/arch/s390/include/asm/sparsemem.h b/arch/s390/include/asm/sparsemem.h
index 545d219e6a2d..0fb34027d3f6 100644
--- a/arch/s390/include/asm/sparsemem.h
+++ b/arch/s390/include/asm/sparsemem.h
@@ -4,8 +4,8 @@
4#ifdef CONFIG_64BIT 4#ifdef CONFIG_64BIT
5 5
6#define SECTION_SIZE_BITS 28 6#define SECTION_SIZE_BITS 28
7#define MAX_PHYSADDR_BITS 42 7#define MAX_PHYSADDR_BITS 46
8#define MAX_PHYSMEM_BITS 42 8#define MAX_PHYSMEM_BITS 46
9 9
10#else 10#else
11 11
diff --git a/arch/s390/include/asm/syscall.h b/arch/s390/include/asm/syscall.h
index b239ff53b189..fb214dd9b7e0 100644
--- a/arch/s390/include/asm/syscall.h
+++ b/arch/s390/include/asm/syscall.h
@@ -27,7 +27,7 @@ static inline long syscall_get_nr(struct task_struct *task,
27 struct pt_regs *regs) 27 struct pt_regs *regs)
28{ 28{
29 return test_tsk_thread_flag(task, TIF_SYSCALL) ? 29 return test_tsk_thread_flag(task, TIF_SYSCALL) ?
30 (regs->svc_code & 0xffff) : -1; 30 (regs->int_code & 0xffff) : -1;
31} 31}
32 32
33static inline void syscall_rollback(struct task_struct *task, 33static inline void syscall_rollback(struct task_struct *task,
diff --git a/arch/s390/include/asm/system.h b/arch/s390/include/asm/system.h
index ef573c1d71a7..d73cc6b60000 100644
--- a/arch/s390/include/asm/system.h
+++ b/arch/s390/include/asm/system.h
@@ -20,8 +20,6 @@
20 20
21struct task_struct; 21struct task_struct;
22 22
23extern int sysctl_userprocess_debug;
24
25extern struct task_struct *__switch_to(void *, void *); 23extern struct task_struct *__switch_to(void *, void *);
26extern void update_per_regs(struct task_struct *task); 24extern void update_per_regs(struct task_struct *task);
27 25
diff --git a/arch/s390/include/asm/topology.h b/arch/s390/include/asm/topology.h
index 005d77d8ae2a..0837de80c351 100644
--- a/arch/s390/include/asm/topology.h
+++ b/arch/s390/include/asm/topology.h
@@ -4,6 +4,10 @@
4#include <linux/cpumask.h> 4#include <linux/cpumask.h>
5#include <asm/sysinfo.h> 5#include <asm/sysinfo.h>
6 6
7struct cpu;
8
9#ifdef CONFIG_SCHED_BOOK
10
7extern unsigned char cpu_core_id[NR_CPUS]; 11extern unsigned char cpu_core_id[NR_CPUS];
8extern cpumask_t cpu_core_map[NR_CPUS]; 12extern cpumask_t cpu_core_map[NR_CPUS];
9 13
@@ -16,8 +20,6 @@ static inline const struct cpumask *cpu_coregroup_mask(int cpu)
16#define topology_core_cpumask(cpu) (&cpu_core_map[cpu]) 20#define topology_core_cpumask(cpu) (&cpu_core_map[cpu])
17#define mc_capable() (1) 21#define mc_capable() (1)
18 22
19#ifdef CONFIG_SCHED_BOOK
20
21extern unsigned char cpu_book_id[NR_CPUS]; 23extern unsigned char cpu_book_id[NR_CPUS];
22extern cpumask_t cpu_book_map[NR_CPUS]; 24extern cpumask_t cpu_book_map[NR_CPUS];
23 25
@@ -29,19 +31,45 @@ static inline const struct cpumask *cpu_book_mask(int cpu)
29#define topology_book_id(cpu) (cpu_book_id[cpu]) 31#define topology_book_id(cpu) (cpu_book_id[cpu])
30#define topology_book_cpumask(cpu) (&cpu_book_map[cpu]) 32#define topology_book_cpumask(cpu) (&cpu_book_map[cpu])
31 33
32#endif /* CONFIG_SCHED_BOOK */ 34int topology_cpu_init(struct cpu *);
33
34int topology_set_cpu_management(int fc); 35int topology_set_cpu_management(int fc);
35void topology_schedule_update(void); 36void topology_schedule_update(void);
36void store_topology(struct sysinfo_15_1_x *info); 37void store_topology(struct sysinfo_15_1_x *info);
38void topology_expect_change(void);
39
40#else /* CONFIG_SCHED_BOOK */
41
42static inline void topology_schedule_update(void) { }
43static inline int topology_cpu_init(struct cpu *cpu) { return 0; }
44static inline void topology_expect_change(void) { }
37 45
38#define POLARIZATION_UNKNWN (-1) 46#endif /* CONFIG_SCHED_BOOK */
47
48#define POLARIZATION_UNKNOWN (-1)
39#define POLARIZATION_HRZ (0) 49#define POLARIZATION_HRZ (0)
40#define POLARIZATION_VL (1) 50#define POLARIZATION_VL (1)
41#define POLARIZATION_VM (2) 51#define POLARIZATION_VM (2)
42#define POLARIZATION_VH (3) 52#define POLARIZATION_VH (3)
43 53
44#ifdef CONFIG_SMP 54extern int cpu_polarization[];
55
56static inline void cpu_set_polarization(int cpu, int val)
57{
58#ifdef CONFIG_SCHED_BOOK
59 cpu_polarization[cpu] = val;
60#endif
61}
62
63static inline int cpu_read_polarization(int cpu)
64{
65#ifdef CONFIG_SCHED_BOOK
66 return cpu_polarization[cpu];
67#else
68 return POLARIZATION_HRZ;
69#endif
70}
71
72#ifdef CONFIG_SCHED_BOOK
45void s390_init_cpu_topology(void); 73void s390_init_cpu_topology(void);
46#else 74#else
47static inline void s390_init_cpu_topology(void) 75static inline void s390_init_cpu_topology(void)
diff --git a/arch/s390/include/asm/unistd.h b/arch/s390/include/asm/unistd.h
index 58de4c91c333..8a8008fe7b8f 100644
--- a/arch/s390/include/asm/unistd.h
+++ b/arch/s390/include/asm/unistd.h
@@ -398,6 +398,7 @@
398#define __ARCH_WANT_SYS_SIGNAL 398#define __ARCH_WANT_SYS_SIGNAL
399#define __ARCH_WANT_SYS_UTIME 399#define __ARCH_WANT_SYS_UTIME
400#define __ARCH_WANT_SYS_SOCKETCALL 400#define __ARCH_WANT_SYS_SOCKETCALL
401#define __ARCH_WANT_SYS_IPC
401#define __ARCH_WANT_SYS_FADVISE64 402#define __ARCH_WANT_SYS_FADVISE64
402#define __ARCH_WANT_SYS_GETPGRP 403#define __ARCH_WANT_SYS_GETPGRP
403#define __ARCH_WANT_SYS_LLSEEK 404#define __ARCH_WANT_SYS_LLSEEK
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile
index dd4f07640919..7d9ec924e7e7 100644
--- a/arch/s390/kernel/Makefile
+++ b/arch/s390/kernel/Makefile
@@ -32,7 +32,8 @@ extra-y += head.o init_task.o vmlinux.lds
32extra-y += $(if $(CONFIG_64BIT),head64.o,head31.o) 32extra-y += $(if $(CONFIG_64BIT),head64.o,head31.o)
33 33
34obj-$(CONFIG_MODULES) += s390_ksyms.o module.o 34obj-$(CONFIG_MODULES) += s390_ksyms.o module.o
35obj-$(CONFIG_SMP) += smp.o topology.o 35obj-$(CONFIG_SMP) += smp.o
36obj-$(CONFIG_SCHED_BOOK) += topology.o
36obj-$(CONFIG_SMP) += $(if $(CONFIG_64BIT),switch_cpu64.o, \ 37obj-$(CONFIG_SMP) += $(if $(CONFIG_64BIT),switch_cpu64.o, \
37 switch_cpu.o) 38 switch_cpu.o)
38obj-$(CONFIG_HIBERNATION) += suspend.o swsusp_asm64.o 39obj-$(CONFIG_HIBERNATION) += suspend.o swsusp_asm64.o
diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c
index 751318765e2e..6e6a72e66d60 100644
--- a/arch/s390/kernel/asm-offsets.c
+++ b/arch/s390/kernel/asm-offsets.c
@@ -45,7 +45,8 @@ int main(void)
45 DEFINE(__PT_PSW, offsetof(struct pt_regs, psw)); 45 DEFINE(__PT_PSW, offsetof(struct pt_regs, psw));
46 DEFINE(__PT_GPRS, offsetof(struct pt_regs, gprs)); 46 DEFINE(__PT_GPRS, offsetof(struct pt_regs, gprs));
47 DEFINE(__PT_ORIG_GPR2, offsetof(struct pt_regs, orig_gpr2)); 47 DEFINE(__PT_ORIG_GPR2, offsetof(struct pt_regs, orig_gpr2));
48 DEFINE(__PT_SVC_CODE, offsetof(struct pt_regs, svc_code)); 48 DEFINE(__PT_INT_CODE, offsetof(struct pt_regs, int_code));
49 DEFINE(__PT_INT_PARM_LONG, offsetof(struct pt_regs, int_parm_long));
49 DEFINE(__PT_SIZE, sizeof(struct pt_regs)); 50 DEFINE(__PT_SIZE, sizeof(struct pt_regs));
50 BLANK(); 51 BLANK();
51 DEFINE(__SF_BACKCHAIN, offsetof(struct stack_frame, back_chain)); 52 DEFINE(__SF_BACKCHAIN, offsetof(struct stack_frame, back_chain));
@@ -108,7 +109,9 @@ int main(void)
108 DEFINE(__LC_PGM_NEW_PSW, offsetof(struct _lowcore, program_new_psw)); 109 DEFINE(__LC_PGM_NEW_PSW, offsetof(struct _lowcore, program_new_psw));
109 DEFINE(__LC_MCK_NEW_PSW, offsetof(struct _lowcore, mcck_new_psw)); 110 DEFINE(__LC_MCK_NEW_PSW, offsetof(struct _lowcore, mcck_new_psw));
110 DEFINE(__LC_IO_NEW_PSW, offsetof(struct _lowcore, io_new_psw)); 111 DEFINE(__LC_IO_NEW_PSW, offsetof(struct _lowcore, io_new_psw));
111 DEFINE(__LC_SAVE_AREA, offsetof(struct _lowcore, save_area)); 112 DEFINE(__LC_SAVE_AREA_SYNC, offsetof(struct _lowcore, save_area_sync));
113 DEFINE(__LC_SAVE_AREA_ASYNC, offsetof(struct _lowcore, save_area_async));
114 DEFINE(__LC_SAVE_AREA_RESTART, offsetof(struct _lowcore, save_area_restart));
112 DEFINE(__LC_RETURN_PSW, offsetof(struct _lowcore, return_psw)); 115 DEFINE(__LC_RETURN_PSW, offsetof(struct _lowcore, return_psw));
113 DEFINE(__LC_RETURN_MCCK_PSW, offsetof(struct _lowcore, return_mcck_psw)); 116 DEFINE(__LC_RETURN_MCCK_PSW, offsetof(struct _lowcore, return_mcck_psw));
114 DEFINE(__LC_SYNC_ENTER_TIMER, offsetof(struct _lowcore, sync_enter_timer)); 117 DEFINE(__LC_SYNC_ENTER_TIMER, offsetof(struct _lowcore, sync_enter_timer));
@@ -150,7 +153,6 @@ int main(void)
150 DEFINE(__LC_LAST_BREAK, offsetof(struct _lowcore, breaking_event_addr)); 153 DEFINE(__LC_LAST_BREAK, offsetof(struct _lowcore, breaking_event_addr));
151 DEFINE(__LC_VDSO_PER_CPU, offsetof(struct _lowcore, vdso_per_cpu_data)); 154 DEFINE(__LC_VDSO_PER_CPU, offsetof(struct _lowcore, vdso_per_cpu_data));
152 DEFINE(__LC_GMAP, offsetof(struct _lowcore, gmap)); 155 DEFINE(__LC_GMAP, offsetof(struct _lowcore, gmap));
153 DEFINE(__LC_CMF_HPP, offsetof(struct _lowcore, cmf_hpp));
154 DEFINE(__GMAP_ASCE, offsetof(struct gmap, asce)); 156 DEFINE(__GMAP_ASCE, offsetof(struct gmap, asce));
155#endif /* CONFIG_32BIT */ 157#endif /* CONFIG_32BIT */
156 return 0; 158 return 0;
diff --git a/arch/s390/kernel/base.S b/arch/s390/kernel/base.S
index f8828d38fa6e..3aa4d00aaf50 100644
--- a/arch/s390/kernel/base.S
+++ b/arch/s390/kernel/base.S
@@ -33,7 +33,7 @@ s390_base_mcck_handler_fn:
33 .previous 33 .previous
34 34
35ENTRY(s390_base_ext_handler) 35ENTRY(s390_base_ext_handler)
36 stmg %r0,%r15,__LC_SAVE_AREA 36 stmg %r0,%r15,__LC_SAVE_AREA_ASYNC
37 basr %r13,0 37 basr %r13,0
380: aghi %r15,-STACK_FRAME_OVERHEAD 380: aghi %r15,-STACK_FRAME_OVERHEAD
39 larl %r1,s390_base_ext_handler_fn 39 larl %r1,s390_base_ext_handler_fn
@@ -41,7 +41,7 @@ ENTRY(s390_base_ext_handler)
41 ltgr %r1,%r1 41 ltgr %r1,%r1
42 jz 1f 42 jz 1f
43 basr %r14,%r1 43 basr %r14,%r1
441: lmg %r0,%r15,__LC_SAVE_AREA 441: lmg %r0,%r15,__LC_SAVE_AREA_ASYNC
45 ni __LC_EXT_OLD_PSW+1,0xfd # clear wait state bit 45 ni __LC_EXT_OLD_PSW+1,0xfd # clear wait state bit
46 lpswe __LC_EXT_OLD_PSW 46 lpswe __LC_EXT_OLD_PSW
47 47
@@ -53,7 +53,7 @@ s390_base_ext_handler_fn:
53 .previous 53 .previous
54 54
55ENTRY(s390_base_pgm_handler) 55ENTRY(s390_base_pgm_handler)
56 stmg %r0,%r15,__LC_SAVE_AREA 56 stmg %r0,%r15,__LC_SAVE_AREA_SYNC
57 basr %r13,0 57 basr %r13,0
580: aghi %r15,-STACK_FRAME_OVERHEAD 580: aghi %r15,-STACK_FRAME_OVERHEAD
59 larl %r1,s390_base_pgm_handler_fn 59 larl %r1,s390_base_pgm_handler_fn
@@ -61,7 +61,7 @@ ENTRY(s390_base_pgm_handler)
61 ltgr %r1,%r1 61 ltgr %r1,%r1
62 jz 1f 62 jz 1f
63 basr %r14,%r1 63 basr %r14,%r1
64 lmg %r0,%r15,__LC_SAVE_AREA 64 lmg %r0,%r15,__LC_SAVE_AREA_SYNC
65 lpswe __LC_PGM_OLD_PSW 65 lpswe __LC_PGM_OLD_PSW
661: lpswe disabled_wait_psw-0b(%r13) 661: lpswe disabled_wait_psw-0b(%r13)
67 67
@@ -142,7 +142,7 @@ s390_base_mcck_handler_fn:
142 .previous 142 .previous
143 143
144ENTRY(s390_base_ext_handler) 144ENTRY(s390_base_ext_handler)
145 stm %r0,%r15,__LC_SAVE_AREA 145 stm %r0,%r15,__LC_SAVE_AREA_ASYNC
146 basr %r13,0 146 basr %r13,0
1470: ahi %r15,-STACK_FRAME_OVERHEAD 1470: ahi %r15,-STACK_FRAME_OVERHEAD
148 l %r1,2f-0b(%r13) 148 l %r1,2f-0b(%r13)
@@ -150,7 +150,7 @@ ENTRY(s390_base_ext_handler)
150 ltr %r1,%r1 150 ltr %r1,%r1
151 jz 1f 151 jz 1f
152 basr %r14,%r1 152 basr %r14,%r1
1531: lm %r0,%r15,__LC_SAVE_AREA 1531: lm %r0,%r15,__LC_SAVE_AREA_ASYNC
154 ni __LC_EXT_OLD_PSW+1,0xfd # clear wait state bit 154 ni __LC_EXT_OLD_PSW+1,0xfd # clear wait state bit
155 lpsw __LC_EXT_OLD_PSW 155 lpsw __LC_EXT_OLD_PSW
156 156
@@ -164,7 +164,7 @@ s390_base_ext_handler_fn:
164 .previous 164 .previous
165 165
166ENTRY(s390_base_pgm_handler) 166ENTRY(s390_base_pgm_handler)
167 stm %r0,%r15,__LC_SAVE_AREA 167 stm %r0,%r15,__LC_SAVE_AREA_SYNC
168 basr %r13,0 168 basr %r13,0
1690: ahi %r15,-STACK_FRAME_OVERHEAD 1690: ahi %r15,-STACK_FRAME_OVERHEAD
170 l %r1,2f-0b(%r13) 170 l %r1,2f-0b(%r13)
@@ -172,7 +172,7 @@ ENTRY(s390_base_pgm_handler)
172 ltr %r1,%r1 172 ltr %r1,%r1
173 jz 1f 173 jz 1f
174 basr %r14,%r1 174 basr %r14,%r1
175 lm %r0,%r15,__LC_SAVE_AREA 175 lm %r0,%r15,__LC_SAVE_AREA_SYNC
176 lpsw __LC_PGM_OLD_PSW 176 lpsw __LC_PGM_OLD_PSW
177 177
1781: lpsw disabled_wait_psw-0b(%r13) 1781: lpsw disabled_wait_psw-0b(%r13)
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c
index 84a982898448..ab64bdbab2ae 100644
--- a/arch/s390/kernel/compat_linux.c
+++ b/arch/s390/kernel/compat_linux.c
@@ -278,9 +278,6 @@ asmlinkage long sys32_ipc(u32 call, int first, int second, int third, u32 ptr)
278{ 278{
279 if (call >> 16) /* hack for backward compatibility */ 279 if (call >> 16) /* hack for backward compatibility */
280 return -EINVAL; 280 return -EINVAL;
281
282 call &= 0xffff;
283
284 switch (call) { 281 switch (call) {
285 case SEMTIMEDOP: 282 case SEMTIMEDOP:
286 return compat_sys_semtimedop(first, compat_ptr(ptr), 283 return compat_sys_semtimedop(first, compat_ptr(ptr),
diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c
index 4f68c81d3ffa..6fe78c2f95d9 100644
--- a/arch/s390/kernel/compat_signal.c
+++ b/arch/s390/kernel/compat_signal.c
@@ -501,8 +501,12 @@ static int setup_frame32(int sig, struct k_sigaction *ka,
501 501
502 /* We forgot to include these in the sigcontext. 502 /* We forgot to include these in the sigcontext.
503 To avoid breaking binary compatibility, they are passed as args. */ 503 To avoid breaking binary compatibility, they are passed as args. */
504 regs->gprs[4] = current->thread.trap_no; 504 if (sig == SIGSEGV || sig == SIGBUS || sig == SIGILL ||
505 regs->gprs[5] = current->thread.prot_addr; 505 sig == SIGTRAP || sig == SIGFPE) {
506 /* set extra registers only for synchronous signals */
507 regs->gprs[4] = regs->int_code & 127;
508 regs->gprs[5] = regs->int_parm_long;
509 }
506 510
507 /* Place signal number on stack to allow backtrace from handler. */ 511 /* Place signal number on stack to allow backtrace from handler. */
508 if (__put_user(regs->gprs[2], (int __force __user *) &frame->signo)) 512 if (__put_user(regs->gprs[2], (int __force __user *) &frame->signo))
@@ -544,9 +548,9 @@ static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info,
544 /* Set up to return from userspace. If provided, use a stub 548 /* Set up to return from userspace. If provided, use a stub
545 already in userspace. */ 549 already in userspace. */
546 if (ka->sa.sa_flags & SA_RESTORER) { 550 if (ka->sa.sa_flags & SA_RESTORER) {
547 regs->gprs[14] = (__u64) ka->sa.sa_restorer; 551 regs->gprs[14] = (__u64) ka->sa.sa_restorer | PSW32_ADDR_AMODE;
548 } else { 552 } else {
549 regs->gprs[14] = (__u64) frame->retcode; 553 regs->gprs[14] = (__u64) frame->retcode | PSW32_ADDR_AMODE;
550 err |= __put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn, 554 err |= __put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn,
551 (u16 __force __user *)(frame->retcode)); 555 (u16 __force __user *)(frame->retcode));
552 } 556 }
diff --git a/arch/s390/kernel/dis.c b/arch/s390/kernel/dis.c
index 45df6d456aa1..e2f847599c8e 100644
--- a/arch/s390/kernel/dis.c
+++ b/arch/s390/kernel/dis.c
@@ -1578,10 +1578,15 @@ void show_code(struct pt_regs *regs)
1578 ptr += sprintf(ptr, "%s Code:", mode); 1578 ptr += sprintf(ptr, "%s Code:", mode);
1579 hops = 0; 1579 hops = 0;
1580 while (start < end && hops < 8) { 1580 while (start < end && hops < 8) {
1581 *ptr++ = (start == 32) ? '>' : ' '; 1581 opsize = insn_length(code[start]);
1582 if (start + opsize == 32)
1583 *ptr++ = '#';
1584 else if (start == 32)
1585 *ptr++ = '>';
1586 else
1587 *ptr++ = ' ';
1582 addr = regs->psw.addr + start - 32; 1588 addr = regs->psw.addr + start - 32;
1583 ptr += sprintf(ptr, ONELONG, addr); 1589 ptr += sprintf(ptr, ONELONG, addr);
1584 opsize = insn_length(code[start]);
1585 if (start + opsize >= end) 1590 if (start + opsize >= end)
1586 break; 1591 break;
1587 for (i = 0; i < opsize; i++) 1592 for (i = 0; i < opsize; i++)
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c
index c9ffe0025197..52098d6dfaa7 100644
--- a/arch/s390/kernel/early.c
+++ b/arch/s390/kernel/early.c
@@ -434,18 +434,22 @@ static void __init append_to_cmdline(size_t (*ipl_data)(char *, size_t))
434 } 434 }
435} 435}
436 436
437static void __init setup_boot_command_line(void) 437static inline int has_ebcdic_char(const char *str)
438{ 438{
439 int i; 439 int i;
440 440
441 /* convert arch command line to ascii */ 441 for (i = 0; str[i]; i++)
442 for (i = 0; i < ARCH_COMMAND_LINE_SIZE; i++) 442 if (str[i] & 0x80)
443 if (COMMAND_LINE[i] & 0x80) 443 return 1;
444 break; 444 return 0;
445 if (i < ARCH_COMMAND_LINE_SIZE) 445}
446 EBCASC(COMMAND_LINE, ARCH_COMMAND_LINE_SIZE);
447 COMMAND_LINE[ARCH_COMMAND_LINE_SIZE-1] = 0;
448 446
447static void __init setup_boot_command_line(void)
448{
449 COMMAND_LINE[ARCH_COMMAND_LINE_SIZE - 1] = 0;
450 /* convert arch command line to ascii if necessary */
451 if (has_ebcdic_char(COMMAND_LINE))
452 EBCASC(COMMAND_LINE, ARCH_COMMAND_LINE_SIZE);
449 /* copy arch command line */ 453 /* copy arch command line */
450 strlcpy(boot_command_line, strstrip(COMMAND_LINE), 454 strlcpy(boot_command_line, strstrip(COMMAND_LINE),
451 ARCH_COMMAND_LINE_SIZE); 455 ARCH_COMMAND_LINE_SIZE);
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index b13157057e02..3705700ed374 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -19,32 +19,22 @@
19#include <asm/unistd.h> 19#include <asm/unistd.h>
20#include <asm/page.h> 20#include <asm/page.h>
21 21
22/* 22__PT_R0 = __PT_GPRS
23 * Stack layout for the system_call stack entry. 23__PT_R1 = __PT_GPRS + 4
24 * The first few entries are identical to the user_regs_struct. 24__PT_R2 = __PT_GPRS + 8
25 */ 25__PT_R3 = __PT_GPRS + 12
26SP_PTREGS = STACK_FRAME_OVERHEAD 26__PT_R4 = __PT_GPRS + 16
27SP_ARGS = STACK_FRAME_OVERHEAD + __PT_ARGS 27__PT_R5 = __PT_GPRS + 20
28SP_PSW = STACK_FRAME_OVERHEAD + __PT_PSW 28__PT_R6 = __PT_GPRS + 24
29SP_R0 = STACK_FRAME_OVERHEAD + __PT_GPRS 29__PT_R7 = __PT_GPRS + 28
30SP_R1 = STACK_FRAME_OVERHEAD + __PT_GPRS + 4 30__PT_R8 = __PT_GPRS + 32
31SP_R2 = STACK_FRAME_OVERHEAD + __PT_GPRS + 8 31__PT_R9 = __PT_GPRS + 36
32SP_R3 = STACK_FRAME_OVERHEAD + __PT_GPRS + 12 32__PT_R10 = __PT_GPRS + 40
33SP_R4 = STACK_FRAME_OVERHEAD + __PT_GPRS + 16 33__PT_R11 = __PT_GPRS + 44
34SP_R5 = STACK_FRAME_OVERHEAD + __PT_GPRS + 20 34__PT_R12 = __PT_GPRS + 48
35SP_R6 = STACK_FRAME_OVERHEAD + __PT_GPRS + 24 35__PT_R13 = __PT_GPRS + 524
36SP_R7 = STACK_FRAME_OVERHEAD + __PT_GPRS + 28 36__PT_R14 = __PT_GPRS + 56
37SP_R8 = STACK_FRAME_OVERHEAD + __PT_GPRS + 32 37__PT_R15 = __PT_GPRS + 60
38SP_R9 = STACK_FRAME_OVERHEAD + __PT_GPRS + 36
39SP_R10 = STACK_FRAME_OVERHEAD + __PT_GPRS + 40
40SP_R11 = STACK_FRAME_OVERHEAD + __PT_GPRS + 44
41SP_R12 = STACK_FRAME_OVERHEAD + __PT_GPRS + 48
42SP_R13 = STACK_FRAME_OVERHEAD + __PT_GPRS + 52
43SP_R14 = STACK_FRAME_OVERHEAD + __PT_GPRS + 56
44SP_R15 = STACK_FRAME_OVERHEAD + __PT_GPRS + 60
45SP_ORIG_R2 = STACK_FRAME_OVERHEAD + __PT_ORIG_GPR2
46SP_SVC_CODE = STACK_FRAME_OVERHEAD + __PT_SVC_CODE
47SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE
48 38
49_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ 39_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
50 _TIF_MCCK_PENDING | _TIF_PER_TRAP ) 40 _TIF_MCCK_PENDING | _TIF_PER_TRAP )
@@ -58,133 +48,91 @@ STACK_SIZE = 1 << STACK_SHIFT
58 48
59#define BASED(name) name-system_call(%r13) 49#define BASED(name) name-system_call(%r13)
60 50
61#ifdef CONFIG_TRACE_IRQFLAGS
62 .macro TRACE_IRQS_ON 51 .macro TRACE_IRQS_ON
52#ifdef CONFIG_TRACE_IRQFLAGS
63 basr %r2,%r0 53 basr %r2,%r0
64 l %r1,BASED(.Ltrace_irq_on_caller) 54 l %r1,BASED(.Lhardirqs_on)
65 basr %r14,%r1 55 basr %r14,%r1 # call trace_hardirqs_on_caller
56#endif
66 .endm 57 .endm
67 58
68 .macro TRACE_IRQS_OFF 59 .macro TRACE_IRQS_OFF
60#ifdef CONFIG_TRACE_IRQFLAGS
69 basr %r2,%r0 61 basr %r2,%r0
70 l %r1,BASED(.Ltrace_irq_off_caller) 62 l %r1,BASED(.Lhardirqs_off)
71 basr %r14,%r1 63 basr %r14,%r1 # call trace_hardirqs_off_caller
72 .endm
73#else
74#define TRACE_IRQS_ON
75#define TRACE_IRQS_OFF
76#endif 64#endif
65 .endm
77 66
78#ifdef CONFIG_LOCKDEP
79 .macro LOCKDEP_SYS_EXIT 67 .macro LOCKDEP_SYS_EXIT
80 tm SP_PSW+1(%r15),0x01 # returning to user ? 68#ifdef CONFIG_LOCKDEP
81 jz 0f 69 tm __PT_PSW+1(%r11),0x01 # returning to user ?
70 jz .+10
82 l %r1,BASED(.Llockdep_sys_exit) 71 l %r1,BASED(.Llockdep_sys_exit)
83 basr %r14,%r1 72 basr %r14,%r1 # call lockdep_sys_exit
840:
85 .endm
86#else
87#define LOCKDEP_SYS_EXIT
88#endif 73#endif
89
90/*
91 * Register usage in interrupt handlers:
92 * R9 - pointer to current task structure
93 * R13 - pointer to literal pool
94 * R14 - return register for function calls
95 * R15 - kernel stack pointer
96 */
97
98 .macro UPDATE_VTIME lc_from,lc_to,lc_sum
99 lm %r10,%r11,\lc_from
100 sl %r10,\lc_to
101 sl %r11,\lc_to+4
102 bc 3,BASED(0f)
103 sl %r10,BASED(.Lc_1)
1040: al %r10,\lc_sum
105 al %r11,\lc_sum+4
106 bc 12,BASED(1f)
107 al %r10,BASED(.Lc_1)
1081: stm %r10,%r11,\lc_sum
109 .endm
110
111 .macro SAVE_ALL_SVC psworg,savearea
112 stm %r12,%r15,\savearea
113 l %r13,__LC_SVC_NEW_PSW+4 # load &system_call to %r13
114 l %r15,__LC_KERNEL_STACK # problem state -> load ksp
115 s %r15,BASED(.Lc_spsize) # make room for registers & psw
116 .endm
117
118 .macro SAVE_ALL_BASE savearea
119 stm %r12,%r15,\savearea
120 l %r13,__LC_SVC_NEW_PSW+4 # load &system_call to %r13
121 .endm 74 .endm
122 75
123 .macro SAVE_ALL_PGM psworg,savearea 76 .macro CHECK_STACK stacksize,savearea
124 tm \psworg+1,0x01 # test problem state bit
125#ifdef CONFIG_CHECK_STACK 77#ifdef CONFIG_CHECK_STACK
126 bnz BASED(1f) 78 tml %r15,\stacksize - CONFIG_STACK_GUARD
127 tml %r15,STACK_SIZE - CONFIG_STACK_GUARD 79 la %r14,\savearea
128 bnz BASED(2f) 80 jz stack_overflow
129 la %r12,\psworg
130 b BASED(stack_overflow)
131#else
132 bz BASED(2f)
133#endif 81#endif
1341: l %r15,__LC_KERNEL_STACK # problem state -> load ksp
1352: s %r15,BASED(.Lc_spsize) # make room for registers & psw
136 .endm 82 .endm
137 83
138 .macro SAVE_ALL_ASYNC psworg,savearea 84 .macro SWITCH_ASYNC savearea,stack,shift
139 stm %r12,%r15,\savearea 85 tmh %r8,0x0001 # interrupting from user ?
140 l %r13,__LC_SVC_NEW_PSW+4 # load &system_call to %r13 86 jnz 1f
141 la %r12,\psworg 87 lr %r14,%r9
142 tm \psworg+1,0x01 # test problem state bit 88 sl %r14,BASED(.Lcritical_start)
143 bnz BASED(1f) # from user -> load async stack 89 cl %r14,BASED(.Lcritical_length)
144 clc \psworg+4(4),BASED(.Lcritical_end) 90 jhe 0f
145 bhe BASED(0f) 91 la %r11,\savearea # inside critical section, do cleanup
146 clc \psworg+4(4),BASED(.Lcritical_start) 92 bras %r14,cleanup_critical
147 bl BASED(0f) 93 tmh %r8,0x0001 # retest problem state after cleanup
148 l %r14,BASED(.Lcleanup_critical) 94 jnz 1f
149 basr %r14,%r14 950: l %r14,\stack # are we already on the target stack?
150 tm 1(%r12),0x01 # retest problem state after cleanup
151 bnz BASED(1f)
1520: l %r14,__LC_ASYNC_STACK # are we already on the async stack ?
153 slr %r14,%r15 96 slr %r14,%r15
154 sra %r14,STACK_SHIFT 97 sra %r14,\shift
155#ifdef CONFIG_CHECK_STACK 98 jnz 1f
156 bnz BASED(1f) 99 CHECK_STACK 1<<\shift,\savearea
157 tml %r15,STACK_SIZE - CONFIG_STACK_GUARD 100 j 2f
158 bnz BASED(2f) 1011: l %r15,\stack # load target stack
159 b BASED(stack_overflow) 1022: ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
160#else 103 la %r11,STACK_FRAME_OVERHEAD(%r15)
161 bz BASED(2f)
162#endif
1631: l %r15,__LC_ASYNC_STACK
1642: s %r15,BASED(.Lc_spsize) # make room for registers & psw
165 .endm 104 .endm
166 105
167 .macro CREATE_STACK_FRAME savearea 106 .macro ADD64 high,low,timer
168 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) 107 al \high,\timer
169 st %r2,SP_ORIG_R2(%r15) # store original content of gpr 2 108 al \low,\timer+4
170 mvc SP_R12(16,%r15),\savearea # move %r12-%r15 to stack 109 brc 12,.+8
171 stm %r0,%r11,SP_R0(%r15) # store gprs %r0-%r11 to kernel stack 110 ahi \high,1
172 .endm 111 .endm
173 112
174 .macro RESTORE_ALL psworg,sync 113 .macro SUB64 high,low,timer
175 mvc \psworg(8),SP_PSW(%r15) # move user PSW to lowcore 114 sl \high,\timer
176 .if !\sync 115 sl \low,\timer+4
177 ni \psworg+1,0xfd # clear wait state bit 116 brc 3,.+8
178 .endif 117 ahi \high,-1
179 lm %r0,%r15,SP_R0(%r15) # load gprs 0-15 of user 118 .endm
180 stpt __LC_EXIT_TIMER 119
181 lpsw \psworg # back to caller 120 .macro UPDATE_VTIME high,low,enter_timer
121 lm \high,\low,__LC_EXIT_TIMER
122 SUB64 \high,\low,\enter_timer
123 ADD64 \high,\low,__LC_USER_TIMER
124 stm \high,\low,__LC_USER_TIMER
125 lm \high,\low,__LC_LAST_UPDATE_TIMER
126 SUB64 \high,\low,__LC_EXIT_TIMER
127 ADD64 \high,\low,__LC_SYSTEM_TIMER
128 stm \high,\low,__LC_SYSTEM_TIMER
129 mvc __LC_LAST_UPDATE_TIMER(8),\enter_timer
182 .endm 130 .endm
183 131
184 .macro REENABLE_IRQS 132 .macro REENABLE_IRQS
185 mvc __SF_EMPTY(1,%r15),SP_PSW(%r15) 133 st %r8,__LC_RETURN_PSW
186 ni __SF_EMPTY(%r15),0xbf 134 ni __LC_RETURN_PSW,0xbf
187 ssm __SF_EMPTY(%r15) 135 ssm __LC_RETURN_PSW
188 .endm 136 .endm
189 137
190 .section .kprobes.text, "ax" 138 .section .kprobes.text, "ax"
@@ -197,14 +145,13 @@ STACK_SIZE = 1 << STACK_SHIFT
197 * gpr2 = prev 145 * gpr2 = prev
198 */ 146 */
199ENTRY(__switch_to) 147ENTRY(__switch_to)
200 basr %r1,0 148 l %r4,__THREAD_info(%r2) # get thread_info of prev
2010: l %r4,__THREAD_info(%r2) # get thread_info of prev
202 l %r5,__THREAD_info(%r3) # get thread_info of next 149 l %r5,__THREAD_info(%r3) # get thread_info of next
203 tm __TI_flags+3(%r4),_TIF_MCCK_PENDING # machine check pending? 150 tm __TI_flags+3(%r4),_TIF_MCCK_PENDING # machine check pending?
204 bz 1f-0b(%r1) 151 jz 0f
205 ni __TI_flags+3(%r4),255-_TIF_MCCK_PENDING # clear flag in prev 152 ni __TI_flags+3(%r4),255-_TIF_MCCK_PENDING # clear flag in prev
206 oi __TI_flags+3(%r5),_TIF_MCCK_PENDING # set it in next 153 oi __TI_flags+3(%r5),_TIF_MCCK_PENDING # set it in next
2071: stm %r6,%r15,__SF_GPRS(%r15) # store gprs of prev task 1540: stm %r6,%r15,__SF_GPRS(%r15) # store gprs of prev task
208 st %r15,__THREAD_ksp(%r2) # store kernel stack of prev 155 st %r15,__THREAD_ksp(%r2) # store kernel stack of prev
209 l %r15,__THREAD_ksp(%r3) # load kernel stack of next 156 l %r15,__THREAD_ksp(%r3) # load kernel stack of next
210 lctl %c4,%c4,__TASK_pid(%r3) # load pid to control reg. 4 157 lctl %c4,%c4,__TASK_pid(%r3) # load pid to control reg. 4
@@ -224,48 +171,55 @@ __critical_start:
224 171
225ENTRY(system_call) 172ENTRY(system_call)
226 stpt __LC_SYNC_ENTER_TIMER 173 stpt __LC_SYNC_ENTER_TIMER
227sysc_saveall: 174sysc_stm:
228 SAVE_ALL_SVC __LC_SVC_OLD_PSW,__LC_SAVE_AREA 175 stm %r8,%r15,__LC_SAVE_AREA_SYNC
229 CREATE_STACK_FRAME __LC_SAVE_AREA 176 l %r12,__LC_THREAD_INFO
230 l %r12,__LC_THREAD_INFO # load pointer to thread_info struct 177 l %r13,__LC_SVC_NEW_PSW+4
231 mvc SP_PSW(8,%r15),__LC_SVC_OLD_PSW 178sysc_per:
232 mvc SP_SVC_CODE(4,%r15),__LC_SVC_ILC 179 l %r15,__LC_KERNEL_STACK
233 oi __TI_flags+3(%r12),_TIF_SYSCALL 180 ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
181 la %r11,STACK_FRAME_OVERHEAD(%r15) # pointer to pt_regs
234sysc_vtime: 182sysc_vtime:
235 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER 183 UPDATE_VTIME %r8,%r9,__LC_SYNC_ENTER_TIMER
236sysc_stime: 184 stm %r0,%r7,__PT_R0(%r11)
237 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 185 mvc __PT_R8(32,%r11),__LC_SAVE_AREA_SYNC
238sysc_update: 186 mvc __PT_PSW(8,%r11),__LC_SVC_OLD_PSW
239 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 187 mvc __PT_INT_CODE(4,%r11),__LC_SVC_ILC
240sysc_do_svc: 188sysc_do_svc:
241 xr %r7,%r7 189 oi __TI_flags+3(%r12),_TIF_SYSCALL
242 icm %r7,3,SP_SVC_CODE+2(%r15)# load svc number and test for svc 0 190 lh %r8,__PT_INT_CODE+2(%r11)
243 bnz BASED(sysc_nr_ok) # svc number > 0 191 sla %r8,2 # shift and test for svc0
192 jnz sysc_nr_ok
244 # svc 0: system call number in %r1 193 # svc 0: system call number in %r1
245 cl %r1,BASED(.Lnr_syscalls) 194 cl %r1,BASED(.Lnr_syscalls)
246 bnl BASED(sysc_nr_ok) 195 jnl sysc_nr_ok
247 sth %r1,SP_SVC_CODE+2(%r15) 196 sth %r1,__PT_INT_CODE+2(%r11)
248 lr %r7,%r1 # copy svc number to %r7 197 lr %r8,%r1
198 sla %r8,2
249sysc_nr_ok: 199sysc_nr_ok:
250 sll %r7,2 # svc number *4 200 l %r10,BASED(.Lsys_call_table) # 31 bit system call table
251 l %r10,BASED(.Lsysc_table) 201 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
202 st %r2,__PT_ORIG_GPR2(%r11)
203 st %r7,STACK_FRAME_OVERHEAD(%r15)
204 l %r9,0(%r8,%r10) # get system call addr.
252 tm __TI_flags+2(%r12),_TIF_TRACE >> 8 205 tm __TI_flags+2(%r12),_TIF_TRACE >> 8
253 mvc SP_ARGS(4,%r15),SP_R7(%r15) 206 jnz sysc_tracesys
254 l %r8,0(%r7,%r10) # get system call addr. 207 basr %r14,%r9 # call sys_xxxx
255 bnz BASED(sysc_tracesys) 208 st %r2,__PT_R2(%r11) # store return value
256 basr %r14,%r8 # call sys_xxxx
257 st %r2,SP_R2(%r15) # store return value (change R2 on stack)
258 209
259sysc_return: 210sysc_return:
260 LOCKDEP_SYS_EXIT 211 LOCKDEP_SYS_EXIT
261sysc_tif: 212sysc_tif:
262 tm SP_PSW+1(%r15),0x01 # returning to user ? 213 tm __PT_PSW+1(%r11),0x01 # returning to user ?
263 bno BASED(sysc_restore) 214 jno sysc_restore
264 tm __TI_flags+3(%r12),_TIF_WORK_SVC 215 tm __TI_flags+3(%r12),_TIF_WORK_SVC
265 bnz BASED(sysc_work) # there is work to do (signals etc.) 216 jnz sysc_work # check for work
266 ni __TI_flags+3(%r12),255-_TIF_SYSCALL 217 ni __TI_flags+3(%r12),255-_TIF_SYSCALL
267sysc_restore: 218sysc_restore:
268 RESTORE_ALL __LC_RETURN_PSW,1 219 mvc __LC_RETURN_PSW(8),__PT_PSW(%r11)
220 stpt __LC_EXIT_TIMER
221 lm %r0,%r15,__PT_R0(%r11)
222 lpsw __LC_RETURN_PSW
269sysc_done: 223sysc_done:
270 224
271# 225#
@@ -273,16 +227,16 @@ sysc_done:
273# 227#
274sysc_work: 228sysc_work:
275 tm __TI_flags+3(%r12),_TIF_MCCK_PENDING 229 tm __TI_flags+3(%r12),_TIF_MCCK_PENDING
276 bo BASED(sysc_mcck_pending) 230 jo sysc_mcck_pending
277 tm __TI_flags+3(%r12),_TIF_NEED_RESCHED 231 tm __TI_flags+3(%r12),_TIF_NEED_RESCHED
278 bo BASED(sysc_reschedule) 232 jo sysc_reschedule
279 tm __TI_flags+3(%r12),_TIF_SIGPENDING 233 tm __TI_flags+3(%r12),_TIF_SIGPENDING
280 bo BASED(sysc_sigpending) 234 jo sysc_sigpending
281 tm __TI_flags+3(%r12),_TIF_NOTIFY_RESUME 235 tm __TI_flags+3(%r12),_TIF_NOTIFY_RESUME
282 bo BASED(sysc_notify_resume) 236 jo sysc_notify_resume
283 tm __TI_flags+3(%r12),_TIF_PER_TRAP 237 tm __TI_flags+3(%r12),_TIF_PER_TRAP
284 bo BASED(sysc_singlestep) 238 jo sysc_singlestep
285 b BASED(sysc_return) # beware of critical section cleanup 239 j sysc_return # beware of critical section cleanup
286 240
287# 241#
288# _TIF_NEED_RESCHED is set, call schedule 242# _TIF_NEED_RESCHED is set, call schedule
@@ -290,13 +244,13 @@ sysc_work:
290sysc_reschedule: 244sysc_reschedule:
291 l %r1,BASED(.Lschedule) 245 l %r1,BASED(.Lschedule)
292 la %r14,BASED(sysc_return) 246 la %r14,BASED(sysc_return)
293 br %r1 # call scheduler 247 br %r1 # call schedule
294 248
295# 249#
296# _TIF_MCCK_PENDING is set, call handler 250# _TIF_MCCK_PENDING is set, call handler
297# 251#
298sysc_mcck_pending: 252sysc_mcck_pending:
299 l %r1,BASED(.Ls390_handle_mcck) 253 l %r1,BASED(.Lhandle_mcck)
300 la %r14,BASED(sysc_return) 254 la %r14,BASED(sysc_return)
301 br %r1 # TIF bit will be cleared by handler 255 br %r1 # TIF bit will be cleared by handler
302 256
@@ -305,23 +259,24 @@ sysc_mcck_pending:
305# 259#
306sysc_sigpending: 260sysc_sigpending:
307 ni __TI_flags+3(%r12),255-_TIF_PER_TRAP # clear TIF_PER_TRAP 261 ni __TI_flags+3(%r12),255-_TIF_PER_TRAP # clear TIF_PER_TRAP
308 la %r2,SP_PTREGS(%r15) # load pt_regs 262 lr %r2,%r11 # pass pointer to pt_regs
309 l %r1,BASED(.Ldo_signal) 263 l %r1,BASED(.Ldo_signal)
310 basr %r14,%r1 # call do_signal 264 basr %r14,%r1 # call do_signal
311 tm __TI_flags+3(%r12),_TIF_SYSCALL 265 tm __TI_flags+3(%r12),_TIF_SYSCALL
312 bno BASED(sysc_return) 266 jno sysc_return
313 lm %r2,%r6,SP_R2(%r15) # load svc arguments 267 lm %r2,%r7,__PT_R2(%r11) # load svc arguments
314 xr %r7,%r7 # svc 0 returns -ENOSYS 268 xr %r8,%r8 # svc 0 returns -ENOSYS
315 clc SP_SVC_CODE+2(2,%r15),BASED(.Lnr_syscalls+2) 269 clc __PT_INT_CODE+2(2,%r11),BASED(.Lnr_syscalls+2)
316 bnl BASED(sysc_nr_ok) # invalid svc number -> do svc 0 270 jnl sysc_nr_ok # invalid svc number -> do svc 0
317 icm %r7,3,SP_SVC_CODE+2(%r15)# load new svc number 271 lh %r8,__PT_INT_CODE+2(%r11) # load new svc number
318 b BASED(sysc_nr_ok) # restart svc 272 sla %r8,2
273 j sysc_nr_ok # restart svc
319 274
320# 275#
321# _TIF_NOTIFY_RESUME is set, call do_notify_resume 276# _TIF_NOTIFY_RESUME is set, call do_notify_resume
322# 277#
323sysc_notify_resume: 278sysc_notify_resume:
324 la %r2,SP_PTREGS(%r15) # load pt_regs 279 lr %r2,%r11 # pass pointer to pt_regs
325 l %r1,BASED(.Ldo_notify_resume) 280 l %r1,BASED(.Ldo_notify_resume)
326 la %r14,BASED(sysc_return) 281 la %r14,BASED(sysc_return)
327 br %r1 # call do_notify_resume 282 br %r1 # call do_notify_resume
@@ -331,56 +286,57 @@ sysc_notify_resume:
331# 286#
332sysc_singlestep: 287sysc_singlestep:
333 ni __TI_flags+3(%r12),255-(_TIF_SYSCALL | _TIF_PER_TRAP) 288 ni __TI_flags+3(%r12),255-(_TIF_SYSCALL | _TIF_PER_TRAP)
334 la %r2,SP_PTREGS(%r15) # address of register-save area 289 lr %r2,%r11 # pass pointer to pt_regs
335 l %r1,BASED(.Lhandle_per) # load adr. of per handler 290 l %r1,BASED(.Ldo_per_trap)
336 la %r14,BASED(sysc_return) # load adr. of system return 291 la %r14,BASED(sysc_return)
337 br %r1 # branch to do_per_trap 292 br %r1 # call do_per_trap
338 293
339# 294#
340# call tracehook_report_syscall_entry/tracehook_report_syscall_exit before 295# call tracehook_report_syscall_entry/tracehook_report_syscall_exit before
341# and after the system call 296# and after the system call
342# 297#
343sysc_tracesys: 298sysc_tracesys:
344 l %r1,BASED(.Ltrace_entry) 299 l %r1,BASED(.Ltrace_enter)
345 la %r2,SP_PTREGS(%r15) # load pt_regs 300 lr %r2,%r11 # pass pointer to pt_regs
346 la %r3,0 301 la %r3,0
347 xr %r0,%r0 302 xr %r0,%r0
348 icm %r0,3,SP_SVC_CODE(%r15) 303 icm %r0,3,__PT_INT_CODE+2(%r11)
349 st %r0,SP_R2(%r15) 304 st %r0,__PT_R2(%r11)
350 basr %r14,%r1 305 basr %r14,%r1 # call do_syscall_trace_enter
351 cl %r2,BASED(.Lnr_syscalls) 306 cl %r2,BASED(.Lnr_syscalls)
352 bnl BASED(sysc_tracenogo) 307 jnl sysc_tracenogo
353 lr %r7,%r2 308 lr %r8,%r2
354 sll %r7,2 # svc number *4 309 sll %r8,2
355 l %r8,0(%r7,%r10) 310 l %r9,0(%r8,%r10)
356sysc_tracego: 311sysc_tracego:
357 lm %r3,%r6,SP_R3(%r15) 312 lm %r3,%r7,__PT_R3(%r11)
358 mvc SP_ARGS(4,%r15),SP_R7(%r15) 313 st %r7,STACK_FRAME_OVERHEAD(%r15)
359 l %r2,SP_ORIG_R2(%r15) 314 l %r2,__PT_ORIG_GPR2(%r11)
360 basr %r14,%r8 # call sys_xxx 315 basr %r14,%r9 # call sys_xxx
361 st %r2,SP_R2(%r15) # store return value 316 st %r2,__PT_R2(%r11) # store return value
362sysc_tracenogo: 317sysc_tracenogo:
363 tm __TI_flags+2(%r12),_TIF_TRACE >> 8 318 tm __TI_flags+2(%r12),_TIF_TRACE >> 8
364 bz BASED(sysc_return) 319 jz sysc_return
365 l %r1,BASED(.Ltrace_exit) 320 l %r1,BASED(.Ltrace_exit)
366 la %r2,SP_PTREGS(%r15) # load pt_regs 321 lr %r2,%r11 # pass pointer to pt_regs
367 la %r14,BASED(sysc_return) 322 la %r14,BASED(sysc_return)
368 br %r1 323 br %r1 # call do_syscall_trace_exit
369 324
370# 325#
371# a new process exits the kernel with ret_from_fork 326# a new process exits the kernel with ret_from_fork
372# 327#
373ENTRY(ret_from_fork) 328ENTRY(ret_from_fork)
329 la %r11,STACK_FRAME_OVERHEAD(%r15)
330 l %r12,__LC_THREAD_INFO
374 l %r13,__LC_SVC_NEW_PSW+4 331 l %r13,__LC_SVC_NEW_PSW+4
375 l %r12,__LC_THREAD_INFO # load pointer to thread_info struct 332 tm __PT_PSW+1(%r11),0x01 # forking a kernel thread ?
376 tm SP_PSW+1(%r15),0x01 # forking a kernel thread ? 333 jo 0f
377 bo BASED(0f) 334 st %r15,__PT_R15(%r11) # store stack pointer for new kthread
378 st %r15,SP_R15(%r15) # store stack pointer for new kthread 3350: l %r1,BASED(.Lschedule_tail)
3790: l %r1,BASED(.Lschedtail) 336 basr %r14,%r1 # call schedule_tail
380 basr %r14,%r1
381 TRACE_IRQS_ON 337 TRACE_IRQS_ON
382 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 338 ssm __LC_SVC_NEW_PSW # reenable interrupts
383 b BASED(sysc_tracenogo) 339 j sysc_tracenogo
384 340
385# 341#
386# kernel_execve function needs to deal with pt_regs that is not 342# kernel_execve function needs to deal with pt_regs that is not
@@ -390,153 +346,98 @@ ENTRY(kernel_execve)
390 stm %r12,%r15,48(%r15) 346 stm %r12,%r15,48(%r15)
391 lr %r14,%r15 347 lr %r14,%r15
392 l %r13,__LC_SVC_NEW_PSW+4 348 l %r13,__LC_SVC_NEW_PSW+4
393 s %r15,BASED(.Lc_spsize) 349 ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
394 st %r14,__SF_BACKCHAIN(%r15) 350 st %r14,__SF_BACKCHAIN(%r15)
395 la %r12,SP_PTREGS(%r15) 351 la %r12,STACK_FRAME_OVERHEAD(%r15)
396 xc 0(__PT_SIZE,%r12),0(%r12) 352 xc 0(__PT_SIZE,%r12),0(%r12)
397 l %r1,BASED(.Ldo_execve) 353 l %r1,BASED(.Ldo_execve)
398 lr %r5,%r12 354 lr %r5,%r12
399 basr %r14,%r1 355 basr %r14,%r1 # call do_execve
400 ltr %r2,%r2 356 ltr %r2,%r2
401 be BASED(0f) 357 je 0f
402 a %r15,BASED(.Lc_spsize) 358 ahi %r15,(STACK_FRAME_OVERHEAD + __PT_SIZE)
403 lm %r12,%r15,48(%r15) 359 lm %r12,%r15,48(%r15)
404 br %r14 360 br %r14
405 # execve succeeded. 361 # execve succeeded.
4060: stnsm __SF_EMPTY(%r15),0xfc # disable interrupts 3620: ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts
407 l %r15,__LC_KERNEL_STACK # load ksp 363 l %r15,__LC_KERNEL_STACK # load ksp
408 s %r15,BASED(.Lc_spsize) # make room for registers & psw 364 ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
409 mvc SP_PTREGS(__PT_SIZE,%r15),0(%r12) # copy pt_regs 365 la %r11,STACK_FRAME_OVERHEAD(%r15)
366 mvc 0(__PT_SIZE,%r11),0(%r12) # copy pt_regs
410 l %r12,__LC_THREAD_INFO 367 l %r12,__LC_THREAD_INFO
411 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) 368 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
412 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 369 ssm __LC_SVC_NEW_PSW # reenable interrupts
413 l %r1,BASED(.Lexecve_tail) 370 l %r1,BASED(.Lexecve_tail)
414 basr %r14,%r1 371 basr %r14,%r1 # call execve_tail
415 b BASED(sysc_return) 372 j sysc_return
416 373
417/* 374/*
418 * Program check handler routine 375 * Program check handler routine
419 */ 376 */
420 377
421ENTRY(pgm_check_handler) 378ENTRY(pgm_check_handler)
422/*
423 * First we need to check for a special case:
424 * Single stepping an instruction that disables the PER event mask will
425 * cause a PER event AFTER the mask has been set. Example: SVC or LPSW.
426 * For a single stepped SVC the program check handler gets control after
427 * the SVC new PSW has been loaded. But we want to execute the SVC first and
428 * then handle the PER event. Therefore we update the SVC old PSW to point
429 * to the pgm_check_handler and branch to the SVC handler after we checked
430 * if we have to load the kernel stack register.
431 * For every other possible cause for PER event without the PER mask set
432 * we just ignore the PER event (FIXME: is there anything we have to do
433 * for LPSW?).
434 */
435 stpt __LC_SYNC_ENTER_TIMER 379 stpt __LC_SYNC_ENTER_TIMER
436 SAVE_ALL_BASE __LC_SAVE_AREA 380 stm %r8,%r15,__LC_SAVE_AREA_SYNC
437 tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception 381 l %r12,__LC_THREAD_INFO
438 bnz BASED(pgm_per) # got per exception -> special case 382 l %r13,__LC_SVC_NEW_PSW+4
439 SAVE_ALL_PGM __LC_PGM_OLD_PSW,__LC_SAVE_AREA 383 lm %r8,%r9,__LC_PGM_OLD_PSW
440 CREATE_STACK_FRAME __LC_SAVE_AREA 384 tmh %r8,0x0001 # test problem state bit
441 mvc SP_PSW(8,%r15),__LC_PGM_OLD_PSW 385 jnz 1f # -> fault in user space
442 l %r12,__LC_THREAD_INFO # load pointer to thread_info struct 386 tmh %r8,0x4000 # PER bit set in old PSW ?
443 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 387 jnz 0f # -> enabled, can't be a double fault
444 bz BASED(pgm_no_vtime) 388 tm __LC_PGM_ILC+3,0x80 # check for per exception
445 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER 389 jnz pgm_svcper # -> single stepped svc
446 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 3900: CHECK_STACK STACK_SIZE,__LC_SAVE_AREA_SYNC
447 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 391 j 2f
448pgm_no_vtime: 3921: UPDATE_VTIME %r14,%r15,__LC_SYNC_ENTER_TIMER
449 l %r3,__LC_PGM_ILC # load program interruption code 393 l %r15,__LC_KERNEL_STACK
450 l %r4,__LC_TRANS_EXC_CODE 3942: ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
451 REENABLE_IRQS 395 la %r11,STACK_FRAME_OVERHEAD(%r15)
452 la %r8,0x7f 396 stm %r0,%r7,__PT_R0(%r11)
453 nr %r8,%r3 397 mvc __PT_R8(32,%r11),__LC_SAVE_AREA_SYNC
454 sll %r8,2 398 stm %r8,%r9,__PT_PSW(%r11)
455 l %r1,BASED(.Ljump_table) 399 mvc __PT_INT_CODE(4,%r11),__LC_PGM_ILC
456 l %r1,0(%r8,%r1) # load address of handler routine 400 mvc __PT_INT_PARM_LONG(4,%r11),__LC_TRANS_EXC_CODE
457 la %r2,SP_PTREGS(%r15) # address of register-save area 401 tm __LC_PGM_ILC+3,0x80 # check for per exception
458 basr %r14,%r1 # branch to interrupt-handler 402 jz 0f
459pgm_exit:
460 b BASED(sysc_return)
461
462#
463# handle per exception
464#
465pgm_per:
466 tm __LC_PGM_OLD_PSW,0x40 # test if per event recording is on
467 bnz BASED(pgm_per_std) # ok, normal per event from user space
468# ok its one of the special cases, now we need to find out which one
469 clc __LC_PGM_OLD_PSW(8),__LC_SVC_NEW_PSW
470 be BASED(pgm_svcper)
471# no interesting special case, ignore PER event
472 lm %r12,%r15,__LC_SAVE_AREA
473 lpsw 0x28
474
475#
476# Normal per exception
477#
478pgm_per_std:
479 SAVE_ALL_PGM __LC_PGM_OLD_PSW,__LC_SAVE_AREA
480 CREATE_STACK_FRAME __LC_SAVE_AREA
481 mvc SP_PSW(8,%r15),__LC_PGM_OLD_PSW
482 l %r12,__LC_THREAD_INFO # load pointer to thread_info struct
483 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
484 bz BASED(pgm_no_vtime2)
485 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
486 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
487 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
488pgm_no_vtime2:
489 l %r1,__TI_task(%r12) 403 l %r1,__TI_task(%r12)
490 tm SP_PSW+1(%r15),0x01 # kernel per event ? 404 tmh %r8,0x0001 # kernel per event ?
491 bz BASED(kernel_per) 405 jz pgm_kprobe
492 mvc __THREAD_per_cause(2,%r1),__LC_PER_CAUSE 406 oi __TI_flags+3(%r12),_TIF_PER_TRAP
493 mvc __THREAD_per_address(4,%r1),__LC_PER_ADDRESS 407 mvc __THREAD_per_address(4,%r1),__LC_PER_ADDRESS
408 mvc __THREAD_per_cause(2,%r1),__LC_PER_CAUSE
494 mvc __THREAD_per_paid(1,%r1),__LC_PER_PAID 409 mvc __THREAD_per_paid(1,%r1),__LC_PER_PAID
495 oi __TI_flags+3(%r12),_TIF_PER_TRAP # set TIF_PER_TRAP 4100: REENABLE_IRQS
496 l %r3,__LC_PGM_ILC # load program interruption code 411 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
497 l %r4,__LC_TRANS_EXC_CODE
498 REENABLE_IRQS
499 la %r8,0x7f
500 nr %r8,%r3 # clear per-event-bit and ilc
501 be BASED(pgm_exit2) # only per or per+check ?
502 sll %r8,2
503 l %r1,BASED(.Ljump_table) 412 l %r1,BASED(.Ljump_table)
504 l %r1,0(%r8,%r1) # load address of handler routine 413 la %r10,0x7f
505 la %r2,SP_PTREGS(%r15) # address of register-save area 414 n %r10,__PT_INT_CODE(%r11)
415 je sysc_return
416 sll %r10,2
417 l %r1,0(%r10,%r1) # load address of handler routine
418 lr %r2,%r11 # pass pointer to pt_regs
506 basr %r14,%r1 # branch to interrupt-handler 419 basr %r14,%r1 # branch to interrupt-handler
507pgm_exit2: 420 j sysc_return
508 b BASED(sysc_return)
509 421
510# 422#
511# it was a single stepped SVC that is causing all the trouble 423# PER event in supervisor state, must be kprobes
512# 424#
513pgm_svcper: 425pgm_kprobe:
514 SAVE_ALL_PGM __LC_SVC_OLD_PSW,__LC_SAVE_AREA 426 REENABLE_IRQS
515 CREATE_STACK_FRAME __LC_SAVE_AREA 427 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
516 l %r12,__LC_THREAD_INFO # load pointer to thread_info struct 428 l %r1,BASED(.Ldo_per_trap)
517 mvc SP_PSW(8,%r15),__LC_SVC_OLD_PSW 429 lr %r2,%r11 # pass pointer to pt_regs
518 mvc SP_SVC_CODE(4,%r15),__LC_SVC_ILC 430 basr %r14,%r1 # call do_per_trap
519 oi __TI_flags+3(%r12),(_TIF_SYSCALL | _TIF_PER_TRAP) 431 j sysc_return
520 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
521 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
522 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
523 l %r8,__TI_task(%r12)
524 mvc __THREAD_per_cause(2,%r8),__LC_PER_CAUSE
525 mvc __THREAD_per_address(4,%r8),__LC_PER_ADDRESS
526 mvc __THREAD_per_paid(1,%r8),__LC_PER_PAID
527 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
528 lm %r2,%r6,SP_R2(%r15) # load svc arguments
529 b BASED(sysc_do_svc)
530 432
531# 433#
532# per was called from kernel, must be kprobes 434# single stepped system call
533# 435#
534kernel_per: 436pgm_svcper:
535 REENABLE_IRQS 437 oi __TI_flags+3(%r12),_TIF_PER_TRAP
536 la %r2,SP_PTREGS(%r15) # address of register-save area 438 mvc __LC_RETURN_PSW(4),__LC_SVC_NEW_PSW
537 l %r1,BASED(.Lhandle_per) # load adr. of per handler 439 mvc __LC_RETURN_PSW+4(4),BASED(.Lsysc_per)
538 basr %r14,%r1 # branch to do_single_step 440 lpsw __LC_RETURN_PSW # branch to sysc_per and enable irqs
539 b BASED(pgm_exit)
540 441
541/* 442/*
542 * IO interrupt handler routine 443 * IO interrupt handler routine
@@ -545,28 +446,35 @@ kernel_per:
545ENTRY(io_int_handler) 446ENTRY(io_int_handler)
546 stck __LC_INT_CLOCK 447 stck __LC_INT_CLOCK
547 stpt __LC_ASYNC_ENTER_TIMER 448 stpt __LC_ASYNC_ENTER_TIMER
548 SAVE_ALL_ASYNC __LC_IO_OLD_PSW,__LC_SAVE_AREA+16 449 stm %r8,%r15,__LC_SAVE_AREA_ASYNC
549 CREATE_STACK_FRAME __LC_SAVE_AREA+16 450 l %r12,__LC_THREAD_INFO
550 mvc SP_PSW(8,%r15),0(%r12) # move user PSW to stack 451 l %r13,__LC_SVC_NEW_PSW+4
551 l %r12,__LC_THREAD_INFO # load pointer to thread_info struct 452 lm %r8,%r9,__LC_IO_OLD_PSW
552 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 453 tmh %r8,0x0001 # interrupting from user ?
553 bz BASED(io_no_vtime) 454 jz io_skip
554 UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER 455 UPDATE_VTIME %r14,%r15,__LC_ASYNC_ENTER_TIMER
555 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 456io_skip:
556 mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER 457 SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_STACK,STACK_SHIFT
557io_no_vtime: 458 stm %r0,%r7,__PT_R0(%r11)
459 mvc __PT_R8(32,%r11),__LC_SAVE_AREA_ASYNC
460 stm %r8,%r9,__PT_PSW(%r11)
558 TRACE_IRQS_OFF 461 TRACE_IRQS_OFF
559 l %r1,BASED(.Ldo_IRQ) # load address of do_IRQ 462 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
560 la %r2,SP_PTREGS(%r15) # address of register-save area 463 l %r1,BASED(.Ldo_IRQ)
561 basr %r14,%r1 # branch to standard irq handler 464 lr %r2,%r11 # pass pointer to pt_regs
465 basr %r14,%r1 # call do_IRQ
562io_return: 466io_return:
563 LOCKDEP_SYS_EXIT 467 LOCKDEP_SYS_EXIT
564 TRACE_IRQS_ON 468 TRACE_IRQS_ON
565io_tif: 469io_tif:
566 tm __TI_flags+3(%r12),_TIF_WORK_INT 470 tm __TI_flags+3(%r12),_TIF_WORK_INT
567 bnz BASED(io_work) # there is work to do (signals etc.) 471 jnz io_work # there is work to do (signals etc.)
568io_restore: 472io_restore:
569 RESTORE_ALL __LC_RETURN_PSW,0 473 mvc __LC_RETURN_PSW(8),__PT_PSW(%r11)
474 ni __LC_RETURN_PSW+1,0xfd # clean wait state bit
475 stpt __LC_EXIT_TIMER
476 lm %r0,%r15,__PT_R0(%r11)
477 lpsw __LC_RETURN_PSW
570io_done: 478io_done:
571 479
572# 480#
@@ -577,28 +485,29 @@ io_done:
577# Before any work can be done, a switch to the kernel stack is required. 485# Before any work can be done, a switch to the kernel stack is required.
578# 486#
579io_work: 487io_work:
580 tm SP_PSW+1(%r15),0x01 # returning to user ? 488 tm __PT_PSW+1(%r11),0x01 # returning to user ?
581 bo BASED(io_work_user) # yes -> do resched & signal 489 jo io_work_user # yes -> do resched & signal
582#ifdef CONFIG_PREEMPT 490#ifdef CONFIG_PREEMPT
583 # check for preemptive scheduling 491 # check for preemptive scheduling
584 icm %r0,15,__TI_precount(%r12) 492 icm %r0,15,__TI_precount(%r12)
585 bnz BASED(io_restore) # preemption disabled 493 jnz io_restore # preemption disabled
586 tm __TI_flags+3(%r12),_TIF_NEED_RESCHED 494 tm __TI_flags+3(%r12),_TIF_NEED_RESCHED
587 bno BASED(io_restore) 495 jno io_restore
588 # switch to kernel stack 496 # switch to kernel stack
589 l %r1,SP_R15(%r15) 497 l %r1,__PT_R15(%r11)
590 s %r1,BASED(.Lc_spsize) 498 ahi %r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
591 mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) 499 mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
592 xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain 500 xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1)
501 la %r11,STACK_FRAME_OVERHEAD(%r1)
593 lr %r15,%r1 502 lr %r15,%r1
594 # TRACE_IRQS_ON already done at io_return, call 503 # TRACE_IRQS_ON already done at io_return, call
595 # TRACE_IRQS_OFF to keep things symmetrical 504 # TRACE_IRQS_OFF to keep things symmetrical
596 TRACE_IRQS_OFF 505 TRACE_IRQS_OFF
597 l %r1,BASED(.Lpreempt_schedule_irq) 506 l %r1,BASED(.Lpreempt_irq)
598 basr %r14,%r1 # call preempt_schedule_irq 507 basr %r14,%r1 # call preempt_schedule_irq
599 b BASED(io_return) 508 j io_return
600#else 509#else
601 b BASED(io_restore) 510 j io_restore
602#endif 511#endif
603 512
604# 513#
@@ -606,9 +515,10 @@ io_work:
606# 515#
607io_work_user: 516io_work_user:
608 l %r1,__LC_KERNEL_STACK 517 l %r1,__LC_KERNEL_STACK
609 s %r1,BASED(.Lc_spsize) 518 ahi %r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
610 mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) 519 mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
611 xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain 520 xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1)
521 la %r11,STACK_FRAME_OVERHEAD(%r1)
612 lr %r15,%r1 522 lr %r15,%r1
613 523
614# 524#
@@ -618,24 +528,24 @@ io_work_user:
618# 528#
619io_work_tif: 529io_work_tif:
620 tm __TI_flags+3(%r12),_TIF_MCCK_PENDING 530 tm __TI_flags+3(%r12),_TIF_MCCK_PENDING
621 bo BASED(io_mcck_pending) 531 jo io_mcck_pending
622 tm __TI_flags+3(%r12),_TIF_NEED_RESCHED 532 tm __TI_flags+3(%r12),_TIF_NEED_RESCHED
623 bo BASED(io_reschedule) 533 jo io_reschedule
624 tm __TI_flags+3(%r12),_TIF_SIGPENDING 534 tm __TI_flags+3(%r12),_TIF_SIGPENDING
625 bo BASED(io_sigpending) 535 jo io_sigpending
626 tm __TI_flags+3(%r12),_TIF_NOTIFY_RESUME 536 tm __TI_flags+3(%r12),_TIF_NOTIFY_RESUME
627 bo BASED(io_notify_resume) 537 jo io_notify_resume
628 b BASED(io_return) # beware of critical section cleanup 538 j io_return # beware of critical section cleanup
629 539
630# 540#
631# _TIF_MCCK_PENDING is set, call handler 541# _TIF_MCCK_PENDING is set, call handler
632# 542#
633io_mcck_pending: 543io_mcck_pending:
634 # TRACE_IRQS_ON already done at io_return 544 # TRACE_IRQS_ON already done at io_return
635 l %r1,BASED(.Ls390_handle_mcck) 545 l %r1,BASED(.Lhandle_mcck)
636 basr %r14,%r1 # TIF bit will be cleared by handler 546 basr %r14,%r1 # TIF bit will be cleared by handler
637 TRACE_IRQS_OFF 547 TRACE_IRQS_OFF
638 b BASED(io_return) 548 j io_return
639 549
640# 550#
641# _TIF_NEED_RESCHED is set, call schedule 551# _TIF_NEED_RESCHED is set, call schedule
@@ -643,37 +553,37 @@ io_mcck_pending:
643io_reschedule: 553io_reschedule:
644 # TRACE_IRQS_ON already done at io_return 554 # TRACE_IRQS_ON already done at io_return
645 l %r1,BASED(.Lschedule) 555 l %r1,BASED(.Lschedule)
646 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 556 ssm __LC_SVC_NEW_PSW # reenable interrupts
647 basr %r14,%r1 # call scheduler 557 basr %r14,%r1 # call scheduler
648 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts 558 ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts
649 TRACE_IRQS_OFF 559 TRACE_IRQS_OFF
650 b BASED(io_return) 560 j io_return
651 561
652# 562#
653# _TIF_SIGPENDING is set, call do_signal 563# _TIF_SIGPENDING is set, call do_signal
654# 564#
655io_sigpending: 565io_sigpending:
656 # TRACE_IRQS_ON already done at io_return 566 # TRACE_IRQS_ON already done at io_return
657 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
658 la %r2,SP_PTREGS(%r15) # load pt_regs
659 l %r1,BASED(.Ldo_signal) 567 l %r1,BASED(.Ldo_signal)
568 ssm __LC_SVC_NEW_PSW # reenable interrupts
569 lr %r2,%r11 # pass pointer to pt_regs
660 basr %r14,%r1 # call do_signal 570 basr %r14,%r1 # call do_signal
661 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts 571 ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts
662 TRACE_IRQS_OFF 572 TRACE_IRQS_OFF
663 b BASED(io_return) 573 j io_return
664 574
665# 575#
666# _TIF_SIGPENDING is set, call do_signal 576# _TIF_SIGPENDING is set, call do_signal
667# 577#
668io_notify_resume: 578io_notify_resume:
669 # TRACE_IRQS_ON already done at io_return 579 # TRACE_IRQS_ON already done at io_return
670 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
671 la %r2,SP_PTREGS(%r15) # load pt_regs
672 l %r1,BASED(.Ldo_notify_resume) 580 l %r1,BASED(.Ldo_notify_resume)
673 basr %r14,%r1 # call do_signal 581 ssm __LC_SVC_NEW_PSW # reenable interrupts
674 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts 582 lr %r2,%r11 # pass pointer to pt_regs
583 basr %r14,%r1 # call do_notify_resume
584 ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts
675 TRACE_IRQS_OFF 585 TRACE_IRQS_OFF
676 b BASED(io_return) 586 j io_return
677 587
678/* 588/*
679 * External interrupt handler routine 589 * External interrupt handler routine
@@ -682,23 +592,25 @@ io_notify_resume:
682ENTRY(ext_int_handler) 592ENTRY(ext_int_handler)
683 stck __LC_INT_CLOCK 593 stck __LC_INT_CLOCK
684 stpt __LC_ASYNC_ENTER_TIMER 594 stpt __LC_ASYNC_ENTER_TIMER
685 SAVE_ALL_ASYNC __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16 595 stm %r8,%r15,__LC_SAVE_AREA_ASYNC
686 CREATE_STACK_FRAME __LC_SAVE_AREA+16 596 l %r12,__LC_THREAD_INFO
687 mvc SP_PSW(8,%r15),0(%r12) # move user PSW to stack 597 l %r13,__LC_SVC_NEW_PSW+4
688 l %r12,__LC_THREAD_INFO # load pointer to thread_info struct 598 lm %r8,%r9,__LC_EXT_OLD_PSW
689 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 599 tmh %r8,0x0001 # interrupting from user ?
690 bz BASED(ext_no_vtime) 600 jz ext_skip
691 UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER 601 UPDATE_VTIME %r14,%r15,__LC_ASYNC_ENTER_TIMER
692 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 602ext_skip:
693 mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER 603 SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_STACK,STACK_SHIFT
694ext_no_vtime: 604 stm %r0,%r7,__PT_R0(%r11)
605 mvc __PT_R8(32,%r11),__LC_SAVE_AREA_ASYNC
606 stm %r8,%r9,__PT_PSW(%r11)
695 TRACE_IRQS_OFF 607 TRACE_IRQS_OFF
696 la %r2,SP_PTREGS(%r15) # address of register-save area 608 lr %r2,%r11 # pass pointer to pt_regs
697 l %r3,__LC_CPU_ADDRESS # get cpu address + interruption code 609 l %r3,__LC_CPU_ADDRESS # get cpu address + interruption code
698 l %r4,__LC_EXT_PARAMS # get external parameters 610 l %r4,__LC_EXT_PARAMS # get external parameters
699 l %r1,BASED(.Ldo_extint) 611 l %r1,BASED(.Ldo_extint)
700 basr %r14,%r1 612 basr %r14,%r1 # call do_extint
701 b BASED(io_return) 613 j io_return
702 614
703__critical_end: 615__critical_end:
704 616
@@ -710,82 +622,74 @@ ENTRY(mcck_int_handler)
710 stck __LC_MCCK_CLOCK 622 stck __LC_MCCK_CLOCK
711 spt __LC_CPU_TIMER_SAVE_AREA # revalidate cpu timer 623 spt __LC_CPU_TIMER_SAVE_AREA # revalidate cpu timer
712 lm %r0,%r15,__LC_GPREGS_SAVE_AREA # revalidate gprs 624 lm %r0,%r15,__LC_GPREGS_SAVE_AREA # revalidate gprs
713 SAVE_ALL_BASE __LC_SAVE_AREA+32 625 l %r12,__LC_THREAD_INFO
714 la %r12,__LC_MCK_OLD_PSW 626 l %r13,__LC_SVC_NEW_PSW+4
627 lm %r8,%r9,__LC_MCK_OLD_PSW
715 tm __LC_MCCK_CODE,0x80 # system damage? 628 tm __LC_MCCK_CODE,0x80 # system damage?
716 bo BASED(mcck_int_main) # yes -> rest of mcck code invalid 629 jo mcck_panic # yes -> rest of mcck code invalid
717 mvc __LC_MCCK_ENTER_TIMER(8),__LC_CPU_TIMER_SAVE_AREA 630 la %r14,__LC_CPU_TIMER_SAVE_AREA
631 mvc __LC_MCCK_ENTER_TIMER(8),0(%r14)
718 tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid? 632 tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid?
719 bo BASED(1f) 633 jo 3f
720 la %r14,__LC_SYNC_ENTER_TIMER 634 la %r14,__LC_SYNC_ENTER_TIMER
721 clc 0(8,%r14),__LC_ASYNC_ENTER_TIMER 635 clc 0(8,%r14),__LC_ASYNC_ENTER_TIMER
722 bl BASED(0f) 636 jl 0f
723 la %r14,__LC_ASYNC_ENTER_TIMER 637 la %r14,__LC_ASYNC_ENTER_TIMER
7240: clc 0(8,%r14),__LC_EXIT_TIMER 6380: clc 0(8,%r14),__LC_EXIT_TIMER
725 bl BASED(0f) 639 jl 1f
726 la %r14,__LC_EXIT_TIMER 640 la %r14,__LC_EXIT_TIMER
7270: clc 0(8,%r14),__LC_LAST_UPDATE_TIMER 6411: clc 0(8,%r14),__LC_LAST_UPDATE_TIMER
728 bl BASED(0f) 642 jl 2f
729 la %r14,__LC_LAST_UPDATE_TIMER 643 la %r14,__LC_LAST_UPDATE_TIMER
7300: spt 0(%r14) 6442: spt 0(%r14)
731 mvc __LC_MCCK_ENTER_TIMER(8),0(%r14) 645 mvc __LC_MCCK_ENTER_TIMER(8),0(%r14)
7321: tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid? 6463: tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid?
733 bno BASED(mcck_int_main) # no -> skip cleanup critical 647 jno mcck_panic # no -> skip cleanup critical
734 tm __LC_MCK_OLD_PSW+1,0x01 # test problem state bit 648 tm %r8,0x0001 # interrupting from user ?
735 bnz BASED(mcck_int_main) # from user -> load async stack 649 jz mcck_skip
736 clc __LC_MCK_OLD_PSW+4(4),BASED(.Lcritical_end) 650 UPDATE_VTIME %r14,%r15,__LC_MCCK_ENTER_TIMER
737 bhe BASED(mcck_int_main) 651mcck_skip:
738 clc __LC_MCK_OLD_PSW+4(4),BASED(.Lcritical_start) 652 SWITCH_ASYNC __LC_GPREGS_SAVE_AREA+32,__LC_PANIC_STACK,PAGE_SHIFT
739 bl BASED(mcck_int_main) 653 mvc __PT_R0(64,%r11),__LC_GPREGS_SAVE_AREA
740 l %r14,BASED(.Lcleanup_critical) 654 stm %r8,%r9,__PT_PSW(%r11)
741 basr %r14,%r14 655 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
742mcck_int_main: 656 l %r1,BASED(.Ldo_machine_check)
743 l %r14,__LC_PANIC_STACK # are we already on the panic stack? 657 lr %r2,%r11 # pass pointer to pt_regs
744 slr %r14,%r15 658 basr %r14,%r1 # call s390_do_machine_check
745 sra %r14,PAGE_SHIFT 659 tm __PT_PSW+1(%r11),0x01 # returning to user ?
746 be BASED(0f) 660 jno mcck_return
747 l %r15,__LC_PANIC_STACK # load panic stack
7480: s %r15,BASED(.Lc_spsize) # make room for registers & psw
749 CREATE_STACK_FRAME __LC_SAVE_AREA+32
750 mvc SP_PSW(8,%r15),0(%r12)
751 l %r12,__LC_THREAD_INFO # load pointer to thread_info struct
752 tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid?
753 bno BASED(mcck_no_vtime) # no -> skip cleanup critical
754 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
755 bz BASED(mcck_no_vtime)
756 UPDATE_VTIME __LC_EXIT_TIMER,__LC_MCCK_ENTER_TIMER,__LC_USER_TIMER
757 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
758 mvc __LC_LAST_UPDATE_TIMER(8),__LC_MCCK_ENTER_TIMER
759mcck_no_vtime:
760 la %r2,SP_PTREGS(%r15) # load pt_regs
761 l %r1,BASED(.Ls390_mcck)
762 basr %r14,%r1 # call machine check handler
763 tm SP_PSW+1(%r15),0x01 # returning to user ?
764 bno BASED(mcck_return)
765 l %r1,__LC_KERNEL_STACK # switch to kernel stack 661 l %r1,__LC_KERNEL_STACK # switch to kernel stack
766 s %r1,BASED(.Lc_spsize) 662 ahi %r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
767 mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) 663 mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
768 xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain 664 xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1)
665 la %r11,STACK_FRAME_OVERHEAD(%r15)
769 lr %r15,%r1 666 lr %r15,%r1
770 stosm __SF_EMPTY(%r15),0x04 # turn dat on 667 ssm __LC_PGM_NEW_PSW # turn dat on, keep irqs off
771 tm __TI_flags+3(%r12),_TIF_MCCK_PENDING 668 tm __TI_flags+3(%r12),_TIF_MCCK_PENDING
772 bno BASED(mcck_return) 669 jno mcck_return
773 TRACE_IRQS_OFF 670 TRACE_IRQS_OFF
774 l %r1,BASED(.Ls390_handle_mcck) 671 l %r1,BASED(.Lhandle_mcck)
775 basr %r14,%r1 # call machine check handler 672 basr %r14,%r1 # call s390_handle_mcck
776 TRACE_IRQS_ON 673 TRACE_IRQS_ON
777mcck_return: 674mcck_return:
778 mvc __LC_RETURN_MCCK_PSW(8),SP_PSW(%r15) # move return PSW 675 mvc __LC_RETURN_MCCK_PSW(8),__PT_PSW(%r11) # move return PSW
779 ni __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit 676 ni __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit
780 tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ? 677 tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ?
781 bno BASED(0f) 678 jno 0f
782 lm %r0,%r15,SP_R0(%r15) # load gprs 0-15 679 lm %r0,%r15,__PT_R0(%r11)
783 stpt __LC_EXIT_TIMER 680 stpt __LC_EXIT_TIMER
784 lpsw __LC_RETURN_MCCK_PSW # back to caller 681 lpsw __LC_RETURN_MCCK_PSW
7850: lm %r0,%r15,SP_R0(%r15) # load gprs 0-15 6820: lm %r0,%r15,__PT_R0(%r11)
786 lpsw __LC_RETURN_MCCK_PSW # back to caller 683 lpsw __LC_RETURN_MCCK_PSW
787 684
788 RESTORE_ALL __LC_RETURN_MCCK_PSW,0 685mcck_panic:
686 l %r14,__LC_PANIC_STACK
687 slr %r14,%r15
688 sra %r14,PAGE_SHIFT
689 jz 0f
690 l %r15,__LC_PANIC_STACK
6910: ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
692 j mcck_skip
789 693
790/* 694/*
791 * Restart interruption handler, kick starter for additional CPUs 695 * Restart interruption handler, kick starter for additional CPUs
@@ -799,18 +703,18 @@ restart_base:
799 stck __LC_LAST_UPDATE_CLOCK 703 stck __LC_LAST_UPDATE_CLOCK
800 mvc __LC_LAST_UPDATE_TIMER(8),restart_vtime-restart_base(%r1) 704 mvc __LC_LAST_UPDATE_TIMER(8),restart_vtime-restart_base(%r1)
801 mvc __LC_EXIT_TIMER(8),restart_vtime-restart_base(%r1) 705 mvc __LC_EXIT_TIMER(8),restart_vtime-restart_base(%r1)
802 l %r15,__LC_SAVE_AREA+60 # load ksp 706 l %r15,__LC_GPREGS_SAVE_AREA+60 # load ksp
803 lctl %c0,%c15,__LC_CREGS_SAVE_AREA # get new ctl regs 707 lctl %c0,%c15,__LC_CREGS_SAVE_AREA # get new ctl regs
804 lam %a0,%a15,__LC_AREGS_SAVE_AREA 708 lam %a0,%a15,__LC_AREGS_SAVE_AREA
805 lm %r6,%r15,__SF_GPRS(%r15) # load registers from clone 709 lm %r6,%r15,__SF_GPRS(%r15)# load registers from clone
806 l %r1,__LC_THREAD_INFO 710 l %r1,__LC_THREAD_INFO
807 mvc __LC_USER_TIMER(8),__TI_user_timer(%r1) 711 mvc __LC_USER_TIMER(8),__TI_user_timer(%r1)
808 mvc __LC_SYSTEM_TIMER(8),__TI_system_timer(%r1) 712 mvc __LC_SYSTEM_TIMER(8),__TI_system_timer(%r1)
809 xc __LC_STEAL_TIMER(8),__LC_STEAL_TIMER 713 xc __LC_STEAL_TIMER(8),__LC_STEAL_TIMER
810 stosm __SF_EMPTY(%r15),0x04 # now we can turn dat on 714 ssm __LC_PGM_NEW_PSW # turn dat on, keep irqs off
811 basr %r14,0 715 basr %r14,0
812 l %r14,restart_addr-.(%r14) 716 l %r14,restart_addr-.(%r14)
813 basr %r14,%r14 # branch to start_secondary 717 basr %r14,%r14 # call start_secondary
814restart_addr: 718restart_addr:
815 .long start_secondary 719 .long start_secondary
816 .align 8 720 .align 8
@@ -835,19 +739,19 @@ restart_go:
835# PSW restart interrupt handler 739# PSW restart interrupt handler
836# 740#
837ENTRY(psw_restart_int_handler) 741ENTRY(psw_restart_int_handler)
838 st %r15,__LC_SAVE_AREA+48(%r0) # save r15 742 st %r15,__LC_SAVE_AREA_RESTART
839 basr %r15,0 743 basr %r15,0
8400: l %r15,.Lrestart_stack-0b(%r15) # load restart stack 7440: l %r15,.Lrestart_stack-0b(%r15) # load restart stack
841 l %r15,0(%r15) 745 l %r15,0(%r15)
842 ahi %r15,-SP_SIZE # make room for pt_regs 746 ahi %r15,-__PT_SIZE # create pt_regs on stack
843 stm %r0,%r14,SP_R0(%r15) # store gprs %r0-%r14 to stack 747 stm %r0,%r14,__PT_R0(%r15)
844 mvc SP_R15(4,%r15),__LC_SAVE_AREA+48(%r0)# store saved %r15 to stack 748 mvc __PT_R15(4,%r15),__LC_SAVE_AREA_RESTART
845 mvc SP_PSW(8,%r15),__LC_RST_OLD_PSW(%r0) # store restart old psw 749 mvc __PT_PSW(8,%r15),__LC_RST_OLD_PSW # store restart old psw
846 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # set backchain to 0 750 ahi %r15,-STACK_FRAME_OVERHEAD
751 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
847 basr %r14,0 752 basr %r14,0
8481: l %r14,.Ldo_restart-1b(%r14) 7531: l %r14,.Ldo_restart-1b(%r14)
849 basr %r14,%r14 754 basr %r14,%r14
850
851 basr %r14,0 # load disabled wait PSW if 755 basr %r14,0 # load disabled wait PSW if
8522: lpsw restart_psw_crash-2b(%r14) # do_restart returns 7562: lpsw restart_psw_crash-2b(%r14) # do_restart returns
853 .align 4 757 .align 4
@@ -869,215 +773,174 @@ restart_psw_crash:
869 */ 773 */
870stack_overflow: 774stack_overflow:
871 l %r15,__LC_PANIC_STACK # change to panic stack 775 l %r15,__LC_PANIC_STACK # change to panic stack
872 sl %r15,BASED(.Lc_spsize) 776 ahi %r15,-__PT_SIZE # create pt_regs
873 mvc SP_PSW(8,%r15),0(%r12) # move user PSW to stack 777 stm %r0,%r7,__PT_R0(%r15)
874 stm %r0,%r11,SP_R0(%r15) # store gprs %r0-%r11 to kernel stack 778 stm %r8,%r9,__PT_PSW(%r15)
875 la %r1,__LC_SAVE_AREA 779 mvc __PT_R8(32,%r11),0(%r14)
876 ch %r12,BASED(.L0x020) # old psw addr == __LC_SVC_OLD_PSW ? 780 lr %r15,%r11
877 be BASED(0f) 781 ahi %r15,-STACK_FRAME_OVERHEAD
878 ch %r12,BASED(.L0x028) # old psw addr == __LC_PGM_OLD_PSW ? 782 l %r1,BASED(1f)
879 be BASED(0f) 783 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
880 la %r1,__LC_SAVE_AREA+16 784 lr %r2,%r11 # pass pointer to pt_regs
8810: mvc SP_R12(16,%r15),0(%r1) # move %r12-%r15 to stack 785 br %r1 # branch to kernel_stack_overflow
882 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear back chain
883 l %r1,BASED(1f) # branch to kernel_stack_overflow
884 la %r2,SP_PTREGS(%r15) # load pt_regs
885 br %r1
8861: .long kernel_stack_overflow 7861: .long kernel_stack_overflow
887#endif 787#endif
888 788
889cleanup_table_system_call: 789cleanup_table:
890 .long system_call + 0x80000000, sysc_do_svc + 0x80000000 790 .long system_call + 0x80000000
891cleanup_table_sysc_tif: 791 .long sysc_do_svc + 0x80000000
892 .long sysc_tif + 0x80000000, sysc_restore + 0x80000000 792 .long sysc_tif + 0x80000000
893cleanup_table_sysc_restore: 793 .long sysc_restore + 0x80000000
894 .long sysc_restore + 0x80000000, sysc_done + 0x80000000 794 .long sysc_done + 0x80000000
895cleanup_table_io_tif: 795 .long io_tif + 0x80000000
896 .long io_tif + 0x80000000, io_restore + 0x80000000 796 .long io_restore + 0x80000000
897cleanup_table_io_restore: 797 .long io_done + 0x80000000
898 .long io_restore + 0x80000000, io_done + 0x80000000
899 798
900cleanup_critical: 799cleanup_critical:
901 clc 4(4,%r12),BASED(cleanup_table_system_call) 800 cl %r9,BASED(cleanup_table) # system_call
902 bl BASED(0f) 801 jl 0f
903 clc 4(4,%r12),BASED(cleanup_table_system_call+4) 802 cl %r9,BASED(cleanup_table+4) # sysc_do_svc
904 bl BASED(cleanup_system_call) 803 jl cleanup_system_call
9050: 804 cl %r9,BASED(cleanup_table+8) # sysc_tif
906 clc 4(4,%r12),BASED(cleanup_table_sysc_tif) 805 jl 0f
907 bl BASED(0f) 806 cl %r9,BASED(cleanup_table+12) # sysc_restore
908 clc 4(4,%r12),BASED(cleanup_table_sysc_tif+4) 807 jl cleanup_sysc_tif
909 bl BASED(cleanup_sysc_tif) 808 cl %r9,BASED(cleanup_table+16) # sysc_done
9100: 809 jl cleanup_sysc_restore
911 clc 4(4,%r12),BASED(cleanup_table_sysc_restore) 810 cl %r9,BASED(cleanup_table+20) # io_tif
912 bl BASED(0f) 811 jl 0f
913 clc 4(4,%r12),BASED(cleanup_table_sysc_restore+4) 812 cl %r9,BASED(cleanup_table+24) # io_restore
914 bl BASED(cleanup_sysc_restore) 813 jl cleanup_io_tif
9150: 814 cl %r9,BASED(cleanup_table+28) # io_done
916 clc 4(4,%r12),BASED(cleanup_table_io_tif) 815 jl cleanup_io_restore
917 bl BASED(0f) 8160: br %r14
918 clc 4(4,%r12),BASED(cleanup_table_io_tif+4)
919 bl BASED(cleanup_io_tif)
9200:
921 clc 4(4,%r12),BASED(cleanup_table_io_restore)
922 bl BASED(0f)
923 clc 4(4,%r12),BASED(cleanup_table_io_restore+4)
924 bl BASED(cleanup_io_restore)
9250:
926 br %r14
927 817
928cleanup_system_call: 818cleanup_system_call:
929 mvc __LC_RETURN_PSW(8),0(%r12) 819 # check if stpt has been executed
930 clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+4) 820 cl %r9,BASED(cleanup_system_call_insn)
931 bh BASED(0f) 821 jh 0f
932 mvc __LC_SYNC_ENTER_TIMER(8),__LC_MCCK_ENTER_TIMER
933 c %r12,BASED(.Lmck_old_psw)
934 be BASED(0f)
935 mvc __LC_SYNC_ENTER_TIMER(8),__LC_ASYNC_ENTER_TIMER 822 mvc __LC_SYNC_ENTER_TIMER(8),__LC_ASYNC_ENTER_TIMER
9360: c %r12,BASED(.Lmck_old_psw) 823 chi %r11,__LC_SAVE_AREA_ASYNC
937 la %r12,__LC_SAVE_AREA+32 824 je 0f
938 be BASED(0f) 825 mvc __LC_SYNC_ENTER_TIMER(8),__LC_MCCK_ENTER_TIMER
939 la %r12,__LC_SAVE_AREA+16 8260: # check if stm has been executed
9400: clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+8) 827 cl %r9,BASED(cleanup_system_call_insn+4)
941 bhe BASED(cleanup_vtime) 828 jh 0f
942 clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn) 829 mvc __LC_SAVE_AREA_SYNC(32),0(%r11)
943 bh BASED(0f) 8300: # set up saved registers r12, and r13
944 mvc __LC_SAVE_AREA(16),0(%r12) 831 st %r12,16(%r11) # r12 thread-info pointer
9450: st %r13,4(%r12) 832 st %r13,20(%r11) # r13 literal-pool pointer
946 l %r15,__LC_KERNEL_STACK # problem state -> load ksp 833 # check if the user time calculation has been done
947 s %r15,BASED(.Lc_spsize) # make room for registers & psw 834 cl %r9,BASED(cleanup_system_call_insn+8)
948 st %r15,12(%r12) 835 jh 0f
949 CREATE_STACK_FRAME __LC_SAVE_AREA 836 l %r10,__LC_EXIT_TIMER
950 mvc 0(4,%r12),__LC_THREAD_INFO 837 l %r15,__LC_EXIT_TIMER+4
951 l %r12,__LC_THREAD_INFO 838 SUB64 %r10,%r15,__LC_SYNC_ENTER_TIMER
952 mvc SP_PSW(8,%r15),__LC_SVC_OLD_PSW 839 ADD64 %r10,%r15,__LC_USER_TIMER
953 mvc SP_SVC_CODE(4,%r15),__LC_SVC_ILC 840 st %r10,__LC_USER_TIMER
954 oi __TI_flags+3(%r12),_TIF_SYSCALL 841 st %r15,__LC_USER_TIMER+4
955cleanup_vtime: 8420: # check if the system time calculation has been done
956 clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+12) 843 cl %r9,BASED(cleanup_system_call_insn+12)
957 bhe BASED(cleanup_stime) 844 jh 0f
958 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER 845 l %r10,__LC_LAST_UPDATE_TIMER
959cleanup_stime: 846 l %r15,__LC_LAST_UPDATE_TIMER+4
960 clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+16) 847 SUB64 %r10,%r15,__LC_EXIT_TIMER
961 bh BASED(cleanup_update) 848 ADD64 %r10,%r15,__LC_SYSTEM_TIMER
962 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 849 st %r10,__LC_SYSTEM_TIMER
963cleanup_update: 850 st %r15,__LC_SYSTEM_TIMER+4
8510: # update accounting time stamp
964 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 852 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
965 mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_system_call+4) 853 # set up saved register 11
966 la %r12,__LC_RETURN_PSW 854 l %r15,__LC_KERNEL_STACK
855 ahi %r15,-__PT_SIZE
856 st %r15,12(%r11) # r11 pt_regs pointer
857 # fill pt_regs
858 mvc __PT_R8(32,%r15),__LC_SAVE_AREA_SYNC
859 stm %r0,%r7,__PT_R0(%r15)
860 mvc __PT_PSW(8,%r15),__LC_SVC_OLD_PSW
861 mvc __PT_INT_CODE(4,%r15),__LC_SVC_ILC
862 # setup saved register 15
863 ahi %r15,-STACK_FRAME_OVERHEAD
864 st %r15,28(%r11) # r15 stack pointer
865 # set new psw address and exit
866 l %r9,BASED(cleanup_table+4) # sysc_do_svc + 0x80000000
967 br %r14 867 br %r14
968cleanup_system_call_insn: 868cleanup_system_call_insn:
969 .long sysc_saveall + 0x80000000
970 .long system_call + 0x80000000 869 .long system_call + 0x80000000
971 .long sysc_vtime + 0x80000000 870 .long sysc_stm + 0x80000000
972 .long sysc_stime + 0x80000000 871 .long sysc_vtime + 0x80000000 + 36
973 .long sysc_update + 0x80000000 872 .long sysc_vtime + 0x80000000 + 76
974 873
975cleanup_sysc_tif: 874cleanup_sysc_tif:
976 mvc __LC_RETURN_PSW(4),0(%r12) 875 l %r9,BASED(cleanup_table+8) # sysc_tif + 0x80000000
977 mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_sysc_tif)
978 la %r12,__LC_RETURN_PSW
979 br %r14 876 br %r14
980 877
981cleanup_sysc_restore: 878cleanup_sysc_restore:
982 clc 4(4,%r12),BASED(cleanup_sysc_restore_insn) 879 cl %r9,BASED(cleanup_sysc_restore_insn)
983 be BASED(2f) 880 jhe 0f
984 mvc __LC_EXIT_TIMER(8),__LC_MCCK_ENTER_TIMER 881 l %r9,12(%r11) # get saved pointer to pt_regs
985 c %r12,BASED(.Lmck_old_psw) 882 mvc __LC_RETURN_PSW(8),__PT_PSW(%r9)
986 be BASED(0f) 883 mvc 0(32,%r11),__PT_R8(%r9)
987 mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER 884 lm %r0,%r7,__PT_R0(%r9)
9880: clc 4(4,%r12),BASED(cleanup_sysc_restore_insn+4) 8850: lm %r8,%r9,__LC_RETURN_PSW
989 be BASED(2f)
990 mvc __LC_RETURN_PSW(8),SP_PSW(%r15)
991 c %r12,BASED(.Lmck_old_psw)
992 la %r12,__LC_SAVE_AREA+32
993 be BASED(1f)
994 la %r12,__LC_SAVE_AREA+16
9951: mvc 0(16,%r12),SP_R12(%r15)
996 lm %r0,%r11,SP_R0(%r15)
997 l %r15,SP_R15(%r15)
9982: la %r12,__LC_RETURN_PSW
999 br %r14 886 br %r14
1000cleanup_sysc_restore_insn: 887cleanup_sysc_restore_insn:
1001 .long sysc_done - 4 + 0x80000000 888 .long sysc_done - 4 + 0x80000000
1002 .long sysc_done - 8 + 0x80000000
1003 889
1004cleanup_io_tif: 890cleanup_io_tif:
1005 mvc __LC_RETURN_PSW(4),0(%r12) 891 l %r9,BASED(cleanup_table+20) # io_tif + 0x80000000
1006 mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_io_tif)
1007 la %r12,__LC_RETURN_PSW
1008 br %r14 892 br %r14
1009 893
1010cleanup_io_restore: 894cleanup_io_restore:
1011 clc 4(4,%r12),BASED(cleanup_io_restore_insn) 895 cl %r9,BASED(cleanup_io_restore_insn)
1012 be BASED(1f) 896 jhe 0f
1013 mvc __LC_EXIT_TIMER(8),__LC_MCCK_ENTER_TIMER 897 l %r9,12(%r11) # get saved r11 pointer to pt_regs
1014 clc 4(4,%r12),BASED(cleanup_io_restore_insn+4) 898 mvc __LC_RETURN_PSW(8),__PT_PSW(%r9)
1015 be BASED(1f) 899 ni __LC_RETURN_PSW+1,0xfd # clear wait state bit
1016 mvc __LC_RETURN_PSW(8),SP_PSW(%r15) 900 mvc 0(32,%r11),__PT_R8(%r9)
1017 mvc __LC_SAVE_AREA+32(16),SP_R12(%r15) 901 lm %r0,%r7,__PT_R0(%r9)
1018 lm %r0,%r11,SP_R0(%r15) 9020: lm %r8,%r9,__LC_RETURN_PSW
1019 l %r15,SP_R15(%r15)
10201: la %r12,__LC_RETURN_PSW
1021 br %r14 903 br %r14
1022cleanup_io_restore_insn: 904cleanup_io_restore_insn:
1023 .long io_done - 4 + 0x80000000 905 .long io_done - 4 + 0x80000000
1024 .long io_done - 8 + 0x80000000
1025 906
1026/* 907/*
1027 * Integer constants 908 * Integer constants
1028 */ 909 */
1029 .align 4 910 .align 4
1030.Lc_spsize: .long SP_SIZE 911.Lnr_syscalls: .long NR_syscalls
1031.Lc_overhead: .long STACK_FRAME_OVERHEAD
1032.Lnr_syscalls: .long NR_syscalls
1033.L0x018: .short 0x018
1034.L0x020: .short 0x020
1035.L0x028: .short 0x028
1036.L0x030: .short 0x030
1037.L0x038: .short 0x038
1038.Lc_1: .long 1
1039 912
1040/* 913/*
1041 * Symbol constants 914 * Symbol constants
1042 */ 915 */
1043.Ls390_mcck: .long s390_do_machine_check 916.Ldo_machine_check: .long s390_do_machine_check
1044.Ls390_handle_mcck: 917.Lhandle_mcck: .long s390_handle_mcck
1045 .long s390_handle_mcck 918.Ldo_IRQ: .long do_IRQ
1046.Lmck_old_psw: .long __LC_MCK_OLD_PSW 919.Ldo_extint: .long do_extint
1047.Ldo_IRQ: .long do_IRQ 920.Ldo_signal: .long do_signal
1048.Ldo_extint: .long do_extint 921.Ldo_notify_resume: .long do_notify_resume
1049.Ldo_signal: .long do_signal 922.Ldo_per_trap: .long do_per_trap
1050.Ldo_notify_resume: 923.Ldo_execve: .long do_execve
1051 .long do_notify_resume 924.Lexecve_tail: .long execve_tail
1052.Lhandle_per: .long do_per_trap 925.Ljump_table: .long pgm_check_table
1053.Ldo_execve: .long do_execve 926.Lschedule: .long schedule
1054.Lexecve_tail: .long execve_tail
1055.Ljump_table: .long pgm_check_table
1056.Lschedule: .long schedule
1057#ifdef CONFIG_PREEMPT 927#ifdef CONFIG_PREEMPT
1058.Lpreempt_schedule_irq: 928.Lpreempt_irq: .long preempt_schedule_irq
1059 .long preempt_schedule_irq
1060#endif 929#endif
1061.Ltrace_entry: .long do_syscall_trace_enter 930.Ltrace_enter: .long do_syscall_trace_enter
1062.Ltrace_exit: .long do_syscall_trace_exit 931.Ltrace_exit: .long do_syscall_trace_exit
1063.Lschedtail: .long schedule_tail 932.Lschedule_tail: .long schedule_tail
1064.Lsysc_table: .long sys_call_table 933.Lsys_call_table: .long sys_call_table
934.Lsysc_per: .long sysc_per + 0x80000000
1065#ifdef CONFIG_TRACE_IRQFLAGS 935#ifdef CONFIG_TRACE_IRQFLAGS
1066.Ltrace_irq_on_caller: 936.Lhardirqs_on: .long trace_hardirqs_on_caller
1067 .long trace_hardirqs_on_caller 937.Lhardirqs_off: .long trace_hardirqs_off_caller
1068.Ltrace_irq_off_caller:
1069 .long trace_hardirqs_off_caller
1070#endif 938#endif
1071#ifdef CONFIG_LOCKDEP 939#ifdef CONFIG_LOCKDEP
1072.Llockdep_sys_exit: 940.Llockdep_sys_exit: .long lockdep_sys_exit
1073 .long lockdep_sys_exit
1074#endif 941#endif
1075.Lcritical_start: 942.Lcritical_start: .long __critical_start + 0x80000000
1076 .long __critical_start + 0x80000000 943.Lcritical_length: .long __critical_end - __critical_start
1077.Lcritical_end:
1078 .long __critical_end + 0x80000000
1079.Lcleanup_critical:
1080 .long cleanup_critical
1081 944
1082 .section .rodata, "a" 945 .section .rodata, "a"
1083#define SYSCALL(esa,esame,emu) .long esa 946#define SYSCALL(esa,esame,emu) .long esa
diff --git a/arch/s390/kernel/entry.h b/arch/s390/kernel/entry.h
index ef8fb1d6e8d7..bf538aaf407d 100644
--- a/arch/s390/kernel/entry.h
+++ b/arch/s390/kernel/entry.h
@@ -6,15 +6,15 @@
6#include <asm/ptrace.h> 6#include <asm/ptrace.h>
7 7
8 8
9extern void (*pgm_check_table[128])(struct pt_regs *, long, unsigned long); 9extern void (*pgm_check_table[128])(struct pt_regs *);
10extern void *restart_stack; 10extern void *restart_stack;
11 11
12asmlinkage long do_syscall_trace_enter(struct pt_regs *regs); 12asmlinkage long do_syscall_trace_enter(struct pt_regs *regs);
13asmlinkage void do_syscall_trace_exit(struct pt_regs *regs); 13asmlinkage void do_syscall_trace_exit(struct pt_regs *regs);
14 14
15void do_protection_exception(struct pt_regs *, long, unsigned long); 15void do_protection_exception(struct pt_regs *regs);
16void do_dat_exception(struct pt_regs *, long, unsigned long); 16void do_dat_exception(struct pt_regs *regs);
17void do_asce_exception(struct pt_regs *, long, unsigned long); 17void do_asce_exception(struct pt_regs *regs);
18 18
19void do_per_trap(struct pt_regs *regs); 19void do_per_trap(struct pt_regs *regs);
20void syscall_trace(struct pt_regs *regs, int entryexit); 20void syscall_trace(struct pt_regs *regs, int entryexit);
@@ -28,7 +28,7 @@ void do_extint(struct pt_regs *regs, unsigned int, unsigned int, unsigned long);
28void do_restart(void); 28void do_restart(void);
29int __cpuinit start_secondary(void *cpuvoid); 29int __cpuinit start_secondary(void *cpuvoid);
30void __init startup_init(void); 30void __init startup_init(void);
31void die(const char * str, struct pt_regs * regs, long err); 31void die(struct pt_regs *regs, const char *str);
32 32
33void __init time_init(void); 33void __init time_init(void);
34 34
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index 83a93747e2fd..412a7b8783d7 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -19,32 +19,22 @@
19#include <asm/unistd.h> 19#include <asm/unistd.h>
20#include <asm/page.h> 20#include <asm/page.h>
21 21
22/* 22__PT_R0 = __PT_GPRS
23 * Stack layout for the system_call stack entry. 23__PT_R1 = __PT_GPRS + 8
24 * The first few entries are identical to the user_regs_struct. 24__PT_R2 = __PT_GPRS + 16
25 */ 25__PT_R3 = __PT_GPRS + 24
26SP_PTREGS = STACK_FRAME_OVERHEAD 26__PT_R4 = __PT_GPRS + 32
27SP_ARGS = STACK_FRAME_OVERHEAD + __PT_ARGS 27__PT_R5 = __PT_GPRS + 40
28SP_PSW = STACK_FRAME_OVERHEAD + __PT_PSW 28__PT_R6 = __PT_GPRS + 48
29SP_R0 = STACK_FRAME_OVERHEAD + __PT_GPRS 29__PT_R7 = __PT_GPRS + 56
30SP_R1 = STACK_FRAME_OVERHEAD + __PT_GPRS + 8 30__PT_R8 = __PT_GPRS + 64
31SP_R2 = STACK_FRAME_OVERHEAD + __PT_GPRS + 16 31__PT_R9 = __PT_GPRS + 72
32SP_R3 = STACK_FRAME_OVERHEAD + __PT_GPRS + 24 32__PT_R10 = __PT_GPRS + 80
33SP_R4 = STACK_FRAME_OVERHEAD + __PT_GPRS + 32 33__PT_R11 = __PT_GPRS + 88
34SP_R5 = STACK_FRAME_OVERHEAD + __PT_GPRS + 40 34__PT_R12 = __PT_GPRS + 96
35SP_R6 = STACK_FRAME_OVERHEAD + __PT_GPRS + 48 35__PT_R13 = __PT_GPRS + 104
36SP_R7 = STACK_FRAME_OVERHEAD + __PT_GPRS + 56 36__PT_R14 = __PT_GPRS + 112
37SP_R8 = STACK_FRAME_OVERHEAD + __PT_GPRS + 64 37__PT_R15 = __PT_GPRS + 120
38SP_R9 = STACK_FRAME_OVERHEAD + __PT_GPRS + 72
39SP_R10 = STACK_FRAME_OVERHEAD + __PT_GPRS + 80
40SP_R11 = STACK_FRAME_OVERHEAD + __PT_GPRS + 88
41SP_R12 = STACK_FRAME_OVERHEAD + __PT_GPRS + 96
42SP_R13 = STACK_FRAME_OVERHEAD + __PT_GPRS + 104
43SP_R14 = STACK_FRAME_OVERHEAD + __PT_GPRS + 112
44SP_R15 = STACK_FRAME_OVERHEAD + __PT_GPRS + 120
45SP_ORIG_R2 = STACK_FRAME_OVERHEAD + __PT_ORIG_GPR2
46SP_SVC_CODE = STACK_FRAME_OVERHEAD + __PT_SVC_CODE
47SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE
48 38
49STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER 39STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER
50STACK_SIZE = 1 << STACK_SHIFT 40STACK_SIZE = 1 << STACK_SHIFT
@@ -59,154 +49,103 @@ _TIF_EXIT_SIE = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING)
59 49
60#define BASED(name) name-system_call(%r13) 50#define BASED(name) name-system_call(%r13)
61 51
62 .macro SPP newpp
63#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE)
64 tm __LC_MACHINE_FLAGS+6,0x20 # MACHINE_FLAG_SPP
65 jz .+8
66 .insn s,0xb2800000,\newpp
67#endif
68 .endm
69
70 .macro HANDLE_SIE_INTERCEPT
71#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE)
72 tm __TI_flags+6(%r12),_TIF_SIE>>8
73 jz 0f
74 SPP __LC_CMF_HPP # set host id
75 clc SP_PSW+8(8,%r15),BASED(.Lsie_loop)
76 jl 0f
77 clc SP_PSW+8(8,%r15),BASED(.Lsie_done)
78 jhe 0f
79 mvc SP_PSW+8(8,%r15),BASED(.Lsie_loop)
800:
81#endif
82 .endm
83
84#ifdef CONFIG_TRACE_IRQFLAGS
85 .macro TRACE_IRQS_ON 52 .macro TRACE_IRQS_ON
53#ifdef CONFIG_TRACE_IRQFLAGS
86 basr %r2,%r0 54 basr %r2,%r0
87 brasl %r14,trace_hardirqs_on_caller 55 brasl %r14,trace_hardirqs_on_caller
56#endif
88 .endm 57 .endm
89 58
90 .macro TRACE_IRQS_OFF 59 .macro TRACE_IRQS_OFF
60#ifdef CONFIG_TRACE_IRQFLAGS
91 basr %r2,%r0 61 basr %r2,%r0
92 brasl %r14,trace_hardirqs_off_caller 62 brasl %r14,trace_hardirqs_off_caller
93 .endm
94#else
95#define TRACE_IRQS_ON
96#define TRACE_IRQS_OFF
97#endif 63#endif
64 .endm
98 65
99#ifdef CONFIG_LOCKDEP
100 .macro LOCKDEP_SYS_EXIT 66 .macro LOCKDEP_SYS_EXIT
101 tm SP_PSW+1(%r15),0x01 # returning to user ? 67#ifdef CONFIG_LOCKDEP
102 jz 0f 68 tm __PT_PSW+1(%r11),0x01 # returning to user ?
69 jz .+10
103 brasl %r14,lockdep_sys_exit 70 brasl %r14,lockdep_sys_exit
1040:
105 .endm
106#else
107#define LOCKDEP_SYS_EXIT
108#endif 71#endif
109
110 .macro UPDATE_VTIME lc_from,lc_to,lc_sum
111 lg %r10,\lc_from
112 slg %r10,\lc_to
113 alg %r10,\lc_sum
114 stg %r10,\lc_sum
115 .endm 72 .endm
116 73
117/* 74 .macro SPP newpp
118 * Register usage in interrupt handlers: 75#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE)
119 * R9 - pointer to current task structure 76 tm __LC_MACHINE_FLAGS+6,0x20 # MACHINE_FLAG_SPP
120 * R13 - pointer to literal pool 77 jz .+8
121 * R14 - return register for function calls 78 .insn s,0xb2800000,\newpp
122 * R15 - kernel stack pointer 79#endif
123 */ 80 .endm
124 81
125 .macro SAVE_ALL_SVC psworg,savearea 82 .macro HANDLE_SIE_INTERCEPT scratch
126 stmg %r11,%r15,\savearea 83#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE)
127 lg %r15,__LC_KERNEL_STACK # problem state -> load ksp 84 tm __TI_flags+6(%r12),_TIF_SIE>>8
128 aghi %r15,-SP_SIZE # make room for registers & psw 85 jz .+42
129 lg %r11,__LC_LAST_BREAK 86 tm __LC_MACHINE_FLAGS+6,0x20 # MACHINE_FLAG_SPP
87 jz .+8
88 .insn s,0xb2800000,BASED(.Lhost_id) # set host id
89 lgr \scratch,%r9
90 slg \scratch,BASED(.Lsie_loop)
91 clg \scratch,BASED(.Lsie_length)
92 jhe .+10
93 lg %r9,BASED(.Lsie_loop)
94#endif
130 .endm 95 .endm
131 96
132 .macro SAVE_ALL_PGM psworg,savearea 97 .macro CHECK_STACK stacksize,savearea
133 stmg %r11,%r15,\savearea
134 tm \psworg+1,0x01 # test problem state bit
135#ifdef CONFIG_CHECK_STACK 98#ifdef CONFIG_CHECK_STACK
136 jnz 1f 99 tml %r15,\stacksize - CONFIG_STACK_GUARD
137 tml %r15,STACK_SIZE - CONFIG_STACK_GUARD 100 lghi %r14,\savearea
138 jnz 2f 101 jz stack_overflow
139 la %r12,\psworg
140 j stack_overflow
141#else
142 jz 2f
143#endif 102#endif
1441: lg %r15,__LC_KERNEL_STACK # problem state -> load ksp
1452: aghi %r15,-SP_SIZE # make room for registers & psw
146 larl %r13,system_call
147 lg %r11,__LC_LAST_BREAK
148 .endm 103 .endm
149 104
150 .macro SAVE_ALL_ASYNC psworg,savearea 105 .macro SWITCH_ASYNC savearea,stack,shift
151 stmg %r11,%r15,\savearea 106 tmhh %r8,0x0001 # interrupting from user ?
152 larl %r13,system_call 107 jnz 1f
153 lg %r11,__LC_LAST_BREAK 108 lgr %r14,%r9
154 la %r12,\psworg 109 slg %r14,BASED(.Lcritical_start)
155 tm \psworg+1,0x01 # test problem state bit 110 clg %r14,BASED(.Lcritical_length)
156 jnz 1f # from user -> load kernel stack
157 clc \psworg+8(8),BASED(.Lcritical_end)
158 jhe 0f 111 jhe 0f
159 clc \psworg+8(8),BASED(.Lcritical_start) 112 lghi %r11,\savearea # inside critical section, do cleanup
160 jl 0f
161 brasl %r14,cleanup_critical 113 brasl %r14,cleanup_critical
162 tm 1(%r12),0x01 # retest problem state after cleanup 114 tmhh %r8,0x0001 # retest problem state after cleanup
163 jnz 1f 115 jnz 1f
1640: lg %r14,__LC_ASYNC_STACK # are we already on the async. stack ? 1160: lg %r14,\stack # are we already on the target stack?
165 slgr %r14,%r15 117 slgr %r14,%r15
166 srag %r14,%r14,STACK_SHIFT 118 srag %r14,%r14,\shift
167#ifdef CONFIG_CHECK_STACK
168 jnz 1f 119 jnz 1f
169 tml %r15,STACK_SIZE - CONFIG_STACK_GUARD 120 CHECK_STACK 1<<\shift,\savearea
170 jnz 2f 121 j 2f
171 j stack_overflow 1221: lg %r15,\stack # load target stack
172#else 1232: aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
173 jz 2f 124 la %r11,STACK_FRAME_OVERHEAD(%r15)
174#endif
1751: lg %r15,__LC_ASYNC_STACK # load async stack
1762: aghi %r15,-SP_SIZE # make room for registers & psw
177 .endm
178
179 .macro CREATE_STACK_FRAME savearea
180 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
181 stg %r2,SP_ORIG_R2(%r15) # store original content of gpr 2
182 mvc SP_R11(40,%r15),\savearea # move %r11-%r15 to stack
183 stmg %r0,%r10,SP_R0(%r15) # store gprs %r0-%r10 to kernel stack
184 .endm 125 .endm
185 126
186 .macro RESTORE_ALL psworg,sync 127 .macro UPDATE_VTIME scratch,enter_timer
187 mvc \psworg(16),SP_PSW(%r15) # move user PSW to lowcore 128 lg \scratch,__LC_EXIT_TIMER
188 .if !\sync 129 slg \scratch,\enter_timer
189 ni \psworg+1,0xfd # clear wait state bit 130 alg \scratch,__LC_USER_TIMER
190 .endif 131 stg \scratch,__LC_USER_TIMER
191 lg %r14,__LC_VDSO_PER_CPU 132 lg \scratch,__LC_LAST_UPDATE_TIMER
192 lmg %r0,%r13,SP_R0(%r15) # load gprs 0-13 of user 133 slg \scratch,__LC_EXIT_TIMER
193 stpt __LC_EXIT_TIMER 134 alg \scratch,__LC_SYSTEM_TIMER
194 mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER 135 stg \scratch,__LC_SYSTEM_TIMER
195 lmg %r14,%r15,SP_R14(%r15) # load grps 14-15 of user 136 mvc __LC_LAST_UPDATE_TIMER(8),\enter_timer
196 lpswe \psworg # back to caller
197 .endm 137 .endm
198 138
199 .macro LAST_BREAK 139 .macro LAST_BREAK scratch
200 srag %r10,%r11,23 140 srag \scratch,%r10,23
201 jz 0f 141 jz .+10
202 stg %r11,__TI_last_break(%r12) 142 stg %r10,__TI_last_break(%r12)
2030:
204 .endm 143 .endm
205 144
206 .macro REENABLE_IRQS 145 .macro REENABLE_IRQS
207 mvc __SF_EMPTY(1,%r15),SP_PSW(%r15) 146 stg %r8,__LC_RETURN_PSW
208 ni __SF_EMPTY(%r15),0xbf 147 ni __LC_RETURN_PSW,0xbf
209 ssm __SF_EMPTY(%r15) 148 ssm __LC_RETURN_PSW
210 .endm 149 .endm
211 150
212 .section .kprobes.text, "ax" 151 .section .kprobes.text, "ax"
@@ -245,55 +184,66 @@ __critical_start:
245 184
246ENTRY(system_call) 185ENTRY(system_call)
247 stpt __LC_SYNC_ENTER_TIMER 186 stpt __LC_SYNC_ENTER_TIMER
248sysc_saveall: 187sysc_stmg:
249 SAVE_ALL_SVC __LC_SVC_OLD_PSW,__LC_SAVE_AREA 188 stmg %r8,%r15,__LC_SAVE_AREA_SYNC
250 CREATE_STACK_FRAME __LC_SAVE_AREA 189 lg %r10,__LC_LAST_BREAK
251 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct 190 lg %r12,__LC_THREAD_INFO
252 mvc SP_PSW(16,%r15),__LC_SVC_OLD_PSW 191 larl %r13,system_call
253 mvc SP_SVC_CODE(4,%r15),__LC_SVC_ILC 192sysc_per:
254 oi __TI_flags+7(%r12),_TIF_SYSCALL 193 lg %r15,__LC_KERNEL_STACK
194 aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
195 la %r11,STACK_FRAME_OVERHEAD(%r15) # pointer to pt_regs
255sysc_vtime: 196sysc_vtime:
256 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER 197 UPDATE_VTIME %r13,__LC_SYNC_ENTER_TIMER
257sysc_stime: 198 LAST_BREAK %r13
258 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 199 stmg %r0,%r7,__PT_R0(%r11)
259sysc_update: 200 mvc __PT_R8(64,%r11),__LC_SAVE_AREA_SYNC
260 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 201 mvc __PT_PSW(16,%r11),__LC_SVC_OLD_PSW
261 LAST_BREAK 202 mvc __PT_INT_CODE(4,%r11),__LC_SVC_ILC
262sysc_do_svc: 203sysc_do_svc:
263 llgh %r7,SP_SVC_CODE+2(%r15) 204 oi __TI_flags+7(%r12),_TIF_SYSCALL
264 slag %r7,%r7,2 # shift and test for svc 0 205 llgh %r8,__PT_INT_CODE+2(%r11)
206 slag %r8,%r8,2 # shift and test for svc 0
265 jnz sysc_nr_ok 207 jnz sysc_nr_ok
266 # svc 0: system call number in %r1 208 # svc 0: system call number in %r1
267 llgfr %r1,%r1 # clear high word in r1 209 llgfr %r1,%r1 # clear high word in r1
268 cghi %r1,NR_syscalls 210 cghi %r1,NR_syscalls
269 jnl sysc_nr_ok 211 jnl sysc_nr_ok
270 sth %r1,SP_SVC_CODE+2(%r15) 212 sth %r1,__PT_INT_CODE+2(%r11)
271 slag %r7,%r1,2 # shift and test for svc 0 213 slag %r8,%r1,2
272sysc_nr_ok: 214sysc_nr_ok:
273 larl %r10,sys_call_table 215 larl %r10,sys_call_table # 64 bit system call table
274#ifdef CONFIG_COMPAT 216#ifdef CONFIG_COMPAT
275 tm __TI_flags+5(%r12),(_TIF_31BIT>>16) # running in 31 bit mode ? 217 tm __TI_flags+5(%r12),(_TIF_31BIT>>16)
276 jno sysc_noemu 218 jno sysc_noemu
277 larl %r10,sys_call_table_emu # use 31 bit emulation system calls 219 larl %r10,sys_call_table_emu # 31 bit system call table
278sysc_noemu: 220sysc_noemu:
279#endif 221#endif
222 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
223 stg %r2,__PT_ORIG_GPR2(%r11)
224 stg %r7,STACK_FRAME_OVERHEAD(%r15)
225 lgf %r9,0(%r8,%r10) # get system call add.
280 tm __TI_flags+6(%r12),_TIF_TRACE >> 8 226 tm __TI_flags+6(%r12),_TIF_TRACE >> 8
281 mvc SP_ARGS(8,%r15),SP_R7(%r15)
282 lgf %r8,0(%r7,%r10) # load address of system call routine
283 jnz sysc_tracesys 227 jnz sysc_tracesys
284 basr %r14,%r8 # call sys_xxxx 228 basr %r14,%r9 # call sys_xxxx
285 stg %r2,SP_R2(%r15) # store return value (change R2 on stack) 229 stg %r2,__PT_R2(%r11) # store return value
286 230
287sysc_return: 231sysc_return:
288 LOCKDEP_SYS_EXIT 232 LOCKDEP_SYS_EXIT
289sysc_tif: 233sysc_tif:
290 tm SP_PSW+1(%r15),0x01 # returning to user ? 234 tm __PT_PSW+1(%r11),0x01 # returning to user ?
291 jno sysc_restore 235 jno sysc_restore
292 tm __TI_flags+7(%r12),_TIF_WORK_SVC 236 tm __TI_flags+7(%r12),_TIF_WORK_SVC
293 jnz sysc_work # there is work to do (signals etc.) 237 jnz sysc_work # check for work
294 ni __TI_flags+7(%r12),255-_TIF_SYSCALL 238 ni __TI_flags+7(%r12),255-_TIF_SYSCALL
295sysc_restore: 239sysc_restore:
296 RESTORE_ALL __LC_RETURN_PSW,1 240 lg %r14,__LC_VDSO_PER_CPU
241 lmg %r0,%r10,__PT_R0(%r11)
242 mvc __LC_RETURN_PSW(16),__PT_PSW(%r11)
243 stpt __LC_EXIT_TIMER
244 mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
245 lmg %r11,%r15,__PT_R11(%r11)
246 lpswe __LC_RETURN_PSW
297sysc_done: 247sysc_done:
298 248
299# 249#
@@ -317,7 +267,7 @@ sysc_work:
317# 267#
318sysc_reschedule: 268sysc_reschedule:
319 larl %r14,sysc_return 269 larl %r14,sysc_return
320 jg schedule # return point is sysc_return 270 jg schedule
321 271
322# 272#
323# _TIF_MCCK_PENDING is set, call handler 273# _TIF_MCCK_PENDING is set, call handler
@@ -331,33 +281,33 @@ sysc_mcck_pending:
331# 281#
332sysc_sigpending: 282sysc_sigpending:
333 ni __TI_flags+7(%r12),255-_TIF_PER_TRAP # clear TIF_PER_TRAP 283 ni __TI_flags+7(%r12),255-_TIF_PER_TRAP # clear TIF_PER_TRAP
334 la %r2,SP_PTREGS(%r15) # load pt_regs 284 lgr %r2,%r11 # pass pointer to pt_regs
335 brasl %r14,do_signal # call do_signal 285 brasl %r14,do_signal
336 tm __TI_flags+7(%r12),_TIF_SYSCALL 286 tm __TI_flags+7(%r12),_TIF_SYSCALL
337 jno sysc_return 287 jno sysc_return
338 lmg %r2,%r6,SP_R2(%r15) # load svc arguments 288 lmg %r2,%r7,__PT_R2(%r11) # load svc arguments
339 lghi %r7,0 # svc 0 returns -ENOSYS 289 lghi %r8,0 # svc 0 returns -ENOSYS
340 lh %r1,SP_SVC_CODE+2(%r15) # load new svc number 290 lh %r1,__PT_INT_CODE+2(%r11) # load new svc number
341 cghi %r1,NR_syscalls 291 cghi %r1,NR_syscalls
342 jnl sysc_nr_ok # invalid svc number -> do svc 0 292 jnl sysc_nr_ok # invalid svc number -> do svc 0
343 slag %r7,%r1,2 293 slag %r8,%r1,2
344 j sysc_nr_ok # restart svc 294 j sysc_nr_ok # restart svc
345 295
346# 296#
347# _TIF_NOTIFY_RESUME is set, call do_notify_resume 297# _TIF_NOTIFY_RESUME is set, call do_notify_resume
348# 298#
349sysc_notify_resume: 299sysc_notify_resume:
350 la %r2,SP_PTREGS(%r15) # load pt_regs 300 lgr %r2,%r11 # pass pointer to pt_regs
351 larl %r14,sysc_return 301 larl %r14,sysc_return
352 jg do_notify_resume # call do_notify_resume 302 jg do_notify_resume
353 303
354# 304#
355# _TIF_PER_TRAP is set, call do_per_trap 305# _TIF_PER_TRAP is set, call do_per_trap
356# 306#
357sysc_singlestep: 307sysc_singlestep:
358 ni __TI_flags+7(%r12),255-(_TIF_SYSCALL | _TIF_PER_TRAP) 308 ni __TI_flags+7(%r12),255-(_TIF_SYSCALL | _TIF_PER_TRAP)
359 la %r2,SP_PTREGS(%r15) # address of register-save area 309 lgr %r2,%r11 # pass pointer to pt_regs
360 larl %r14,sysc_return # load adr. of system return 310 larl %r14,sysc_return
361 jg do_per_trap 311 jg do_per_trap
362 312
363# 313#
@@ -365,41 +315,41 @@ sysc_singlestep:
365# and after the system call 315# and after the system call
366# 316#
367sysc_tracesys: 317sysc_tracesys:
368 la %r2,SP_PTREGS(%r15) # load pt_regs 318 lgr %r2,%r11 # pass pointer to pt_regs
369 la %r3,0 319 la %r3,0
370 llgh %r0,SP_SVC_CODE+2(%r15) 320 llgh %r0,__PT_INT_CODE+2(%r11)
371 stg %r0,SP_R2(%r15) 321 stg %r0,__PT_R2(%r11)
372 brasl %r14,do_syscall_trace_enter 322 brasl %r14,do_syscall_trace_enter
373 lghi %r0,NR_syscalls 323 lghi %r0,NR_syscalls
374 clgr %r0,%r2 324 clgr %r0,%r2
375 jnh sysc_tracenogo 325 jnh sysc_tracenogo
376 sllg %r7,%r2,2 # svc number *4 326 sllg %r8,%r2,2
377 lgf %r8,0(%r7,%r10) 327 lgf %r9,0(%r8,%r10)
378sysc_tracego: 328sysc_tracego:
379 lmg %r3,%r6,SP_R3(%r15) 329 lmg %r3,%r7,__PT_R3(%r11)
380 mvc SP_ARGS(8,%r15),SP_R7(%r15) 330 stg %r7,STACK_FRAME_OVERHEAD(%r15)
381 lg %r2,SP_ORIG_R2(%r15) 331 lg %r2,__PT_ORIG_GPR2(%r11)
382 basr %r14,%r8 # call sys_xxx 332 basr %r14,%r9 # call sys_xxx
383 stg %r2,SP_R2(%r15) # store return value 333 stg %r2,__PT_R2(%r11) # store return value
384sysc_tracenogo: 334sysc_tracenogo:
385 tm __TI_flags+6(%r12),_TIF_TRACE >> 8 335 tm __TI_flags+6(%r12),_TIF_TRACE >> 8
386 jz sysc_return 336 jz sysc_return
387 la %r2,SP_PTREGS(%r15) # load pt_regs 337 lgr %r2,%r11 # pass pointer to pt_regs
388 larl %r14,sysc_return # return point is sysc_return 338 larl %r14,sysc_return
389 jg do_syscall_trace_exit 339 jg do_syscall_trace_exit
390 340
391# 341#
392# a new process exits the kernel with ret_from_fork 342# a new process exits the kernel with ret_from_fork
393# 343#
394ENTRY(ret_from_fork) 344ENTRY(ret_from_fork)
395 lg %r13,__LC_SVC_NEW_PSW+8 345 la %r11,STACK_FRAME_OVERHEAD(%r15)
396 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct 346 lg %r12,__LC_THREAD_INFO
397 tm SP_PSW+1(%r15),0x01 # forking a kernel thread ? 347 tm __PT_PSW+1(%r11),0x01 # forking a kernel thread ?
398 jo 0f 348 jo 0f
399 stg %r15,SP_R15(%r15) # store stack pointer for new kthread 349 stg %r15,__PT_R15(%r11) # store stack pointer for new kthread
4000: brasl %r14,schedule_tail 3500: brasl %r14,schedule_tail
401 TRACE_IRQS_ON 351 TRACE_IRQS_ON
402 stosm 24(%r15),0x03 # reenable interrupts 352 ssm __LC_SVC_NEW_PSW # reenable interrupts
403 j sysc_tracenogo 353 j sysc_tracenogo
404 354
405# 355#
@@ -409,26 +359,26 @@ ENTRY(ret_from_fork)
409ENTRY(kernel_execve) 359ENTRY(kernel_execve)
410 stmg %r12,%r15,96(%r15) 360 stmg %r12,%r15,96(%r15)
411 lgr %r14,%r15 361 lgr %r14,%r15
412 aghi %r15,-SP_SIZE 362 aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
413 stg %r14,__SF_BACKCHAIN(%r15) 363 stg %r14,__SF_BACKCHAIN(%r15)
414 la %r12,SP_PTREGS(%r15) 364 la %r12,STACK_FRAME_OVERHEAD(%r15)
415 xc 0(__PT_SIZE,%r12),0(%r12) 365 xc 0(__PT_SIZE,%r12),0(%r12)
416 lgr %r5,%r12 366 lgr %r5,%r12
417 brasl %r14,do_execve 367 brasl %r14,do_execve
418 ltgfr %r2,%r2 368 ltgfr %r2,%r2
419 je 0f 369 je 0f
420 aghi %r15,SP_SIZE 370 aghi %r15,(STACK_FRAME_OVERHEAD + __PT_SIZE)
421 lmg %r12,%r15,96(%r15) 371 lmg %r12,%r15,96(%r15)
422 br %r14 372 br %r14
423 # execve succeeded. 373 # execve succeeded.
4240: stnsm __SF_EMPTY(%r15),0xfc # disable interrupts 3740: ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts
425 lg %r15,__LC_KERNEL_STACK # load ksp 375 lg %r15,__LC_KERNEL_STACK # load ksp
426 aghi %r15,-SP_SIZE # make room for registers & psw 376 aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
427 lg %r13,__LC_SVC_NEW_PSW+8 377 la %r11,STACK_FRAME_OVERHEAD(%r15)
428 mvc SP_PTREGS(__PT_SIZE,%r15),0(%r12) # copy pt_regs 378 mvc 0(__PT_SIZE,%r11),0(%r12) # copy pt_regs
429 lg %r12,__LC_THREAD_INFO 379 lg %r12,__LC_THREAD_INFO
430 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) 380 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
431 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 381 ssm __LC_SVC_NEW_PSW # reenable interrupts
432 brasl %r14,execve_tail 382 brasl %r14,execve_tail
433 j sysc_return 383 j sysc_return
434 384
@@ -437,127 +387,72 @@ ENTRY(kernel_execve)
437 */ 387 */
438 388
439ENTRY(pgm_check_handler) 389ENTRY(pgm_check_handler)
440/*
441 * First we need to check for a special case:
442 * Single stepping an instruction that disables the PER event mask will
443 * cause a PER event AFTER the mask has been set. Example: SVC or LPSW.
444 * For a single stepped SVC the program check handler gets control after
445 * the SVC new PSW has been loaded. But we want to execute the SVC first and
446 * then handle the PER event. Therefore we update the SVC old PSW to point
447 * to the pgm_check_handler and branch to the SVC handler after we checked
448 * if we have to load the kernel stack register.
449 * For every other possible cause for PER event without the PER mask set
450 * we just ignore the PER event (FIXME: is there anything we have to do
451 * for LPSW?).
452 */
453 stpt __LC_SYNC_ENTER_TIMER 390 stpt __LC_SYNC_ENTER_TIMER
454 tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception 391 stmg %r8,%r15,__LC_SAVE_AREA_SYNC
455 jnz pgm_per # got per exception -> special case 392 lg %r10,__LC_LAST_BREAK
456 SAVE_ALL_PGM __LC_PGM_OLD_PSW,__LC_SAVE_AREA 393 lg %r12,__LC_THREAD_INFO
457 CREATE_STACK_FRAME __LC_SAVE_AREA 394 larl %r13,system_call
458 mvc SP_PSW(16,%r15),__LC_PGM_OLD_PSW 395 lmg %r8,%r9,__LC_PGM_OLD_PSW
459 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct 396 HANDLE_SIE_INTERCEPT %r14
460 HANDLE_SIE_INTERCEPT 397 tmhh %r8,0x0001 # test problem state bit
461 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 398 jnz 1f # -> fault in user space
462 jz pgm_no_vtime 399 tmhh %r8,0x4000 # PER bit set in old PSW ?
463 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER 400 jnz 0f # -> enabled, can't be a double fault
464 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 401 tm __LC_PGM_ILC+3,0x80 # check for per exception
465 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 402 jnz pgm_svcper # -> single stepped svc
466 LAST_BREAK 4030: CHECK_STACK STACK_SIZE,__LC_SAVE_AREA_SYNC
467pgm_no_vtime: 404 j 2f
468 stg %r11,SP_ARGS(%r15) 4051: UPDATE_VTIME %r14,__LC_SYNC_ENTER_TIMER
469 lgf %r3,__LC_PGM_ILC # load program interruption code 406 LAST_BREAK %r14
470 lg %r4,__LC_TRANS_EXC_CODE 407 lg %r15,__LC_KERNEL_STACK
471 REENABLE_IRQS 4082: aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
472 lghi %r8,0x7f 409 la %r11,STACK_FRAME_OVERHEAD(%r15)
473 ngr %r8,%r3 410 stmg %r0,%r7,__PT_R0(%r11)
474 sll %r8,3 411 mvc __PT_R8(64,%r11),__LC_SAVE_AREA_SYNC
475 larl %r1,pgm_check_table 412 stmg %r8,%r9,__PT_PSW(%r11)
476 lg %r1,0(%r8,%r1) # load address of handler routine 413 mvc __PT_INT_CODE(4,%r11),__LC_PGM_ILC
477 la %r2,SP_PTREGS(%r15) # address of register-save area 414 mvc __PT_INT_PARM_LONG(8,%r11),__LC_TRANS_EXC_CODE
478 basr %r14,%r1 # branch to interrupt-handler 415 stg %r10,__PT_ARGS(%r11)
479pgm_exit: 416 tm __LC_PGM_ILC+3,0x80 # check for per exception
480 j sysc_return 417 jz 0f
481
482#
483# handle per exception
484#
485pgm_per:
486 tm __LC_PGM_OLD_PSW,0x40 # test if per event recording is on
487 jnz pgm_per_std # ok, normal per event from user space
488# ok its one of the special cases, now we need to find out which one
489 clc __LC_PGM_OLD_PSW(16),__LC_SVC_NEW_PSW
490 je pgm_svcper
491# no interesting special case, ignore PER event
492 lpswe __LC_PGM_OLD_PSW
493
494#
495# Normal per exception
496#
497pgm_per_std:
498 SAVE_ALL_PGM __LC_PGM_OLD_PSW,__LC_SAVE_AREA
499 CREATE_STACK_FRAME __LC_SAVE_AREA
500 mvc SP_PSW(16,%r15),__LC_PGM_OLD_PSW
501 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct
502 HANDLE_SIE_INTERCEPT
503 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
504 jz pgm_no_vtime2
505 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
506 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
507 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
508 LAST_BREAK
509pgm_no_vtime2:
510 lg %r1,__TI_task(%r12) 418 lg %r1,__TI_task(%r12)
511 tm SP_PSW+1(%r15),0x01 # kernel per event ? 419 tmhh %r8,0x0001 # kernel per event ?
512 jz kernel_per 420 jz pgm_kprobe
513 mvc __THREAD_per_cause(2,%r1),__LC_PER_CAUSE 421 oi __TI_flags+7(%r12),_TIF_PER_TRAP
514 mvc __THREAD_per_address(8,%r1),__LC_PER_ADDRESS 422 mvc __THREAD_per_address(8,%r1),__LC_PER_ADDRESS
423 mvc __THREAD_per_cause(2,%r1),__LC_PER_CAUSE
515 mvc __THREAD_per_paid(1,%r1),__LC_PER_PAID 424 mvc __THREAD_per_paid(1,%r1),__LC_PER_PAID
516 oi __TI_flags+7(%r12),_TIF_PER_TRAP # set TIF_PER_TRAP 4250: REENABLE_IRQS
517 lgf %r3,__LC_PGM_ILC # load program interruption code 426 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
518 lg %r4,__LC_TRANS_EXC_CODE
519 REENABLE_IRQS
520 lghi %r8,0x7f
521 ngr %r8,%r3 # clear per-event-bit and ilc
522 je pgm_exit2
523 sll %r8,3
524 larl %r1,pgm_check_table 427 larl %r1,pgm_check_table
525 lg %r1,0(%r8,%r1) # load address of handler routine 428 llgh %r10,__PT_INT_CODE+2(%r11)
526 la %r2,SP_PTREGS(%r15) # address of register-save area 429 nill %r10,0x007f
430 sll %r10,3
431 je sysc_return
432 lg %r1,0(%r10,%r1) # load address of handler routine
433 lgr %r2,%r11 # pass pointer to pt_regs
527 basr %r14,%r1 # branch to interrupt-handler 434 basr %r14,%r1 # branch to interrupt-handler
528pgm_exit2:
529 j sysc_return 435 j sysc_return
530 436
531# 437#
532# it was a single stepped SVC that is causing all the trouble 438# PER event in supervisor state, must be kprobes
533# 439#
534pgm_svcper: 440pgm_kprobe:
535 SAVE_ALL_PGM __LC_SVC_OLD_PSW,__LC_SAVE_AREA 441 REENABLE_IRQS
536 CREATE_STACK_FRAME __LC_SAVE_AREA 442 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
537 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct 443 lgr %r2,%r11 # pass pointer to pt_regs
538 mvc SP_PSW(16,%r15),__LC_SVC_OLD_PSW 444 brasl %r14,do_per_trap
539 mvc SP_SVC_CODE(4,%r15),__LC_SVC_ILC 445 j sysc_return
540 oi __TI_flags+7(%r12),(_TIF_SYSCALL | _TIF_PER_TRAP)
541 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
542 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
543 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
544 LAST_BREAK
545 lg %r8,__TI_task(%r12)
546 mvc __THREAD_per_cause(2,%r8),__LC_PER_CAUSE
547 mvc __THREAD_per_address(8,%r8),__LC_PER_ADDRESS
548 mvc __THREAD_per_paid(1,%r8),__LC_PER_PAID
549 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
550 lmg %r2,%r6,SP_R2(%r15) # load svc arguments
551 j sysc_do_svc
552 446
553# 447#
554# per was called from kernel, must be kprobes 448# single stepped system call
555# 449#
556kernel_per: 450pgm_svcper:
557 REENABLE_IRQS 451 oi __TI_flags+7(%r12),_TIF_PER_TRAP
558 la %r2,SP_PTREGS(%r15) # address of register-save area 452 mvc __LC_RETURN_PSW(8),__LC_SVC_NEW_PSW
559 brasl %r14,do_per_trap 453 larl %r14,sysc_per
560 j pgm_exit 454 stg %r14,__LC_RETURN_PSW+8
455 lpswe __LC_RETURN_PSW # branch to sysc_per and enable irqs
561 456
562/* 457/*
563 * IO interrupt handler routine 458 * IO interrupt handler routine
@@ -565,21 +460,25 @@ kernel_per:
565ENTRY(io_int_handler) 460ENTRY(io_int_handler)
566 stck __LC_INT_CLOCK 461 stck __LC_INT_CLOCK
567 stpt __LC_ASYNC_ENTER_TIMER 462 stpt __LC_ASYNC_ENTER_TIMER
568 SAVE_ALL_ASYNC __LC_IO_OLD_PSW,__LC_SAVE_AREA+40 463 stmg %r8,%r15,__LC_SAVE_AREA_ASYNC
569 CREATE_STACK_FRAME __LC_SAVE_AREA+40 464 lg %r10,__LC_LAST_BREAK
570 mvc SP_PSW(16,%r15),0(%r12) # move user PSW to stack 465 lg %r12,__LC_THREAD_INFO
571 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct 466 larl %r13,system_call
572 HANDLE_SIE_INTERCEPT 467 lmg %r8,%r9,__LC_IO_OLD_PSW
573 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 468 HANDLE_SIE_INTERCEPT %r14
574 jz io_no_vtime 469 SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_STACK,STACK_SHIFT
575 UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER 470 tmhh %r8,0x0001 # interrupting from user?
576 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 471 jz io_skip
577 mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER 472 UPDATE_VTIME %r14,__LC_ASYNC_ENTER_TIMER
578 LAST_BREAK 473 LAST_BREAK %r14
579io_no_vtime: 474io_skip:
475 stmg %r0,%r7,__PT_R0(%r11)
476 mvc __PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC
477 stmg %r8,%r9,__PT_PSW(%r11)
580 TRACE_IRQS_OFF 478 TRACE_IRQS_OFF
581 la %r2,SP_PTREGS(%r15) # address of register-save area 479 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
582 brasl %r14,do_IRQ # call standard irq handler 480 lgr %r2,%r11 # pass pointer to pt_regs
481 brasl %r14,do_IRQ
583io_return: 482io_return:
584 LOCKDEP_SYS_EXIT 483 LOCKDEP_SYS_EXIT
585 TRACE_IRQS_ON 484 TRACE_IRQS_ON
@@ -587,7 +486,14 @@ io_tif:
587 tm __TI_flags+7(%r12),_TIF_WORK_INT 486 tm __TI_flags+7(%r12),_TIF_WORK_INT
588 jnz io_work # there is work to do (signals etc.) 487 jnz io_work # there is work to do (signals etc.)
589io_restore: 488io_restore:
590 RESTORE_ALL __LC_RETURN_PSW,0 489 lg %r14,__LC_VDSO_PER_CPU
490 lmg %r0,%r10,__PT_R0(%r11)
491 mvc __LC_RETURN_PSW(16),__PT_PSW(%r11)
492 ni __LC_RETURN_PSW+1,0xfd # clear wait state bit
493 stpt __LC_EXIT_TIMER
494 mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
495 lmg %r11,%r15,__PT_R11(%r11)
496 lpswe __LC_RETURN_PSW
591io_done: 497io_done:
592 498
593# 499#
@@ -600,7 +506,7 @@ io_done:
600# Before any work can be done, a switch to the kernel stack is required. 506# Before any work can be done, a switch to the kernel stack is required.
601# 507#
602io_work: 508io_work:
603 tm SP_PSW+1(%r15),0x01 # returning to user ? 509 tm __PT_PSW+1(%r11),0x01 # returning to user ?
604 jo io_work_user # yes -> do resched & signal 510 jo io_work_user # yes -> do resched & signal
605#ifdef CONFIG_PREEMPT 511#ifdef CONFIG_PREEMPT
606 # check for preemptive scheduling 512 # check for preemptive scheduling
@@ -609,10 +515,11 @@ io_work:
609 tm __TI_flags+7(%r12),_TIF_NEED_RESCHED 515 tm __TI_flags+7(%r12),_TIF_NEED_RESCHED
610 jno io_restore 516 jno io_restore
611 # switch to kernel stack 517 # switch to kernel stack
612 lg %r1,SP_R15(%r15) 518 lg %r1,__PT_R15(%r11)
613 aghi %r1,-SP_SIZE 519 aghi %r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
614 mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) 520 mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
615 xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) # clear back chain 521 xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1)
522 la %r11,STACK_FRAME_OVERHEAD(%r1)
616 lgr %r15,%r1 523 lgr %r15,%r1
617 # TRACE_IRQS_ON already done at io_return, call 524 # TRACE_IRQS_ON already done at io_return, call
618 # TRACE_IRQS_OFF to keep things symmetrical 525 # TRACE_IRQS_OFF to keep things symmetrical
@@ -628,9 +535,10 @@ io_work:
628# 535#
629io_work_user: 536io_work_user:
630 lg %r1,__LC_KERNEL_STACK 537 lg %r1,__LC_KERNEL_STACK
631 aghi %r1,-SP_SIZE 538 aghi %r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
632 mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) 539 mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
633 xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) # clear back chain 540 xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1)
541 la %r11,STACK_FRAME_OVERHEAD(%r1)
634 lgr %r15,%r1 542 lgr %r15,%r1
635 543
636# 544#
@@ -663,9 +571,9 @@ io_mcck_pending:
663# 571#
664io_reschedule: 572io_reschedule:
665 # TRACE_IRQS_ON already done at io_return 573 # TRACE_IRQS_ON already done at io_return
666 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 574 ssm __LC_SVC_NEW_PSW # reenable interrupts
667 brasl %r14,schedule # call scheduler 575 brasl %r14,schedule # call scheduler
668 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts 576 ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts
669 TRACE_IRQS_OFF 577 TRACE_IRQS_OFF
670 j io_return 578 j io_return
671 579
@@ -674,10 +582,10 @@ io_reschedule:
674# 582#
675io_sigpending: 583io_sigpending:
676 # TRACE_IRQS_ON already done at io_return 584 # TRACE_IRQS_ON already done at io_return
677 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 585 ssm __LC_SVC_NEW_PSW # reenable interrupts
678 la %r2,SP_PTREGS(%r15) # load pt_regs 586 lgr %r2,%r11 # pass pointer to pt_regs
679 brasl %r14,do_signal # call do_signal 587 brasl %r14,do_signal
680 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts 588 ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts
681 TRACE_IRQS_OFF 589 TRACE_IRQS_OFF
682 j io_return 590 j io_return
683 591
@@ -686,10 +594,10 @@ io_sigpending:
686# 594#
687io_notify_resume: 595io_notify_resume:
688 # TRACE_IRQS_ON already done at io_return 596 # TRACE_IRQS_ON already done at io_return
689 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 597 ssm __LC_SVC_NEW_PSW # reenable interrupts
690 la %r2,SP_PTREGS(%r15) # load pt_regs 598 lgr %r2,%r11 # pass pointer to pt_regs
691 brasl %r14,do_notify_resume # call do_notify_resume 599 brasl %r14,do_notify_resume
692 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts 600 ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts
693 TRACE_IRQS_OFF 601 TRACE_IRQS_OFF
694 j io_return 602 j io_return
695 603
@@ -699,21 +607,24 @@ io_notify_resume:
699ENTRY(ext_int_handler) 607ENTRY(ext_int_handler)
700 stck __LC_INT_CLOCK 608 stck __LC_INT_CLOCK
701 stpt __LC_ASYNC_ENTER_TIMER 609 stpt __LC_ASYNC_ENTER_TIMER
702 SAVE_ALL_ASYNC __LC_EXT_OLD_PSW,__LC_SAVE_AREA+40 610 stmg %r8,%r15,__LC_SAVE_AREA_ASYNC
703 CREATE_STACK_FRAME __LC_SAVE_AREA+40 611 lg %r10,__LC_LAST_BREAK
704 mvc SP_PSW(16,%r15),0(%r12) # move user PSW to stack 612 lg %r12,__LC_THREAD_INFO
705 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct 613 larl %r13,system_call
706 HANDLE_SIE_INTERCEPT 614 lmg %r8,%r9,__LC_EXT_OLD_PSW
707 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 615 HANDLE_SIE_INTERCEPT %r14
708 jz ext_no_vtime 616 SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_STACK,STACK_SHIFT
709 UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER 617 tmhh %r8,0x0001 # interrupting from user ?
710 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 618 jz ext_skip
711 mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER 619 UPDATE_VTIME %r14,__LC_ASYNC_ENTER_TIMER
712 LAST_BREAK 620 LAST_BREAK %r14
713ext_no_vtime: 621ext_skip:
622 stmg %r0,%r7,__PT_R0(%r11)
623 mvc __PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC
624 stmg %r8,%r9,__PT_PSW(%r11)
714 TRACE_IRQS_OFF 625 TRACE_IRQS_OFF
715 lghi %r1,4096 626 lghi %r1,4096
716 la %r2,SP_PTREGS(%r15) # address of register-save area 627 lgr %r2,%r11 # pass pointer to pt_regs
717 llgf %r3,__LC_CPU_ADDRESS # get cpu address + interruption code 628 llgf %r3,__LC_CPU_ADDRESS # get cpu address + interruption code
718 llgf %r4,__LC_EXT_PARAMS # get external parameter 629 llgf %r4,__LC_EXT_PARAMS # get external parameter
719 lg %r5,__LC_EXT_PARAMS2-4096(%r1) # get 64 bit external parameter 630 lg %r5,__LC_EXT_PARAMS2-4096(%r1) # get 64 bit external parameter
@@ -730,81 +641,77 @@ ENTRY(mcck_int_handler)
730 la %r1,4095 # revalidate r1 641 la %r1,4095 # revalidate r1
731 spt __LC_CPU_TIMER_SAVE_AREA-4095(%r1) # revalidate cpu timer 642 spt __LC_CPU_TIMER_SAVE_AREA-4095(%r1) # revalidate cpu timer
732 lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# revalidate gprs 643 lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# revalidate gprs
733 stmg %r11,%r15,__LC_SAVE_AREA+80 644 lg %r10,__LC_LAST_BREAK
645 lg %r12,__LC_THREAD_INFO
734 larl %r13,system_call 646 larl %r13,system_call
735 lg %r11,__LC_LAST_BREAK 647 lmg %r8,%r9,__LC_MCK_OLD_PSW
736 la %r12,__LC_MCK_OLD_PSW 648 HANDLE_SIE_INTERCEPT %r14
737 tm __LC_MCCK_CODE,0x80 # system damage? 649 tm __LC_MCCK_CODE,0x80 # system damage?
738 jo mcck_int_main # yes -> rest of mcck code invalid 650 jo mcck_panic # yes -> rest of mcck code invalid
739 la %r14,4095 651 lghi %r14,__LC_CPU_TIMER_SAVE_AREA
740 mvc __LC_MCCK_ENTER_TIMER(8),__LC_CPU_TIMER_SAVE_AREA-4095(%r14) 652 mvc __LC_MCCK_ENTER_TIMER(8),0(%r14)
741 tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid? 653 tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid?
742 jo 1f 654 jo 3f
743 la %r14,__LC_SYNC_ENTER_TIMER 655 la %r14,__LC_SYNC_ENTER_TIMER
744 clc 0(8,%r14),__LC_ASYNC_ENTER_TIMER 656 clc 0(8,%r14),__LC_ASYNC_ENTER_TIMER
745 jl 0f 657 jl 0f
746 la %r14,__LC_ASYNC_ENTER_TIMER 658 la %r14,__LC_ASYNC_ENTER_TIMER
7470: clc 0(8,%r14),__LC_EXIT_TIMER 6590: clc 0(8,%r14),__LC_EXIT_TIMER
748 jl 0f 660 jl 1f
749 la %r14,__LC_EXIT_TIMER 661 la %r14,__LC_EXIT_TIMER
7500: clc 0(8,%r14),__LC_LAST_UPDATE_TIMER 6621: clc 0(8,%r14),__LC_LAST_UPDATE_TIMER
751 jl 0f 663 jl 2f
752 la %r14,__LC_LAST_UPDATE_TIMER 664 la %r14,__LC_LAST_UPDATE_TIMER
7530: spt 0(%r14) 6652: spt 0(%r14)
754 mvc __LC_MCCK_ENTER_TIMER(8),0(%r14) 666 mvc __LC_MCCK_ENTER_TIMER(8),0(%r14)
7551: tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid? 6673: tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid?
756 jno mcck_int_main # no -> skip cleanup critical 668 jno mcck_panic # no -> skip cleanup critical
757 tm __LC_MCK_OLD_PSW+1,0x01 # test problem state bit 669 SWITCH_ASYNC __LC_GPREGS_SAVE_AREA+64,__LC_PANIC_STACK,PAGE_SHIFT
758 jnz mcck_int_main # from user -> load kernel stack 670 tm %r8,0x0001 # interrupting from user ?
759 clc __LC_MCK_OLD_PSW+8(8),BASED(.Lcritical_end) 671 jz mcck_skip
760 jhe mcck_int_main 672 UPDATE_VTIME %r14,__LC_MCCK_ENTER_TIMER
761 clc __LC_MCK_OLD_PSW+8(8),BASED(.Lcritical_start) 673 LAST_BREAK %r14
762 jl mcck_int_main 674mcck_skip:
763 brasl %r14,cleanup_critical 675 lghi %r14,__LC_GPREGS_SAVE_AREA
764mcck_int_main: 676 mvc __PT_R0(128,%r11),0(%r14)
765 lg %r14,__LC_PANIC_STACK # are we already on the panic stack? 677 stmg %r8,%r9,__PT_PSW(%r11)
766 slgr %r14,%r15 678 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
767 srag %r14,%r14,PAGE_SHIFT 679 lgr %r2,%r11 # pass pointer to pt_regs
768 jz 0f
769 lg %r15,__LC_PANIC_STACK # load panic stack
7700: aghi %r15,-SP_SIZE # make room for registers & psw
771 CREATE_STACK_FRAME __LC_SAVE_AREA+80
772 mvc SP_PSW(16,%r15),0(%r12)
773 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct
774 tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid?
775 jno mcck_no_vtime # no -> no timer update
776 HANDLE_SIE_INTERCEPT
777 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
778 jz mcck_no_vtime
779 UPDATE_VTIME __LC_EXIT_TIMER,__LC_MCCK_ENTER_TIMER,__LC_USER_TIMER
780 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
781 mvc __LC_LAST_UPDATE_TIMER(8),__LC_MCCK_ENTER_TIMER
782 LAST_BREAK
783mcck_no_vtime:
784 la %r2,SP_PTREGS(%r15) # load pt_regs
785 brasl %r14,s390_do_machine_check 680 brasl %r14,s390_do_machine_check
786 tm SP_PSW+1(%r15),0x01 # returning to user ? 681 tm __PT_PSW+1(%r11),0x01 # returning to user ?
787 jno mcck_return 682 jno mcck_return
788 lg %r1,__LC_KERNEL_STACK # switch to kernel stack 683 lg %r1,__LC_KERNEL_STACK # switch to kernel stack
789 aghi %r1,-SP_SIZE 684 aghi %r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
790 mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) 685 mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
791 xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) # clear back chain 686 xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1)
687 la %r11,STACK_FRAME_OVERHEAD(%r1)
792 lgr %r15,%r1 688 lgr %r15,%r1
793 stosm __SF_EMPTY(%r15),0x04 # turn dat on 689 ssm __LC_PGM_NEW_PSW # turn dat on, keep irqs off
794 tm __TI_flags+7(%r12),_TIF_MCCK_PENDING 690 tm __TI_flags+7(%r12),_TIF_MCCK_PENDING
795 jno mcck_return 691 jno mcck_return
796 TRACE_IRQS_OFF 692 TRACE_IRQS_OFF
797 brasl %r14,s390_handle_mcck 693 brasl %r14,s390_handle_mcck
798 TRACE_IRQS_ON 694 TRACE_IRQS_ON
799mcck_return: 695mcck_return:
800 mvc __LC_RETURN_MCCK_PSW(16),SP_PSW(%r15) # move return PSW 696 lg %r14,__LC_VDSO_PER_CPU
697 lmg %r0,%r10,__PT_R0(%r11)
698 mvc __LC_RETURN_MCCK_PSW(16),__PT_PSW(%r11) # move return PSW
801 ni __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit 699 ni __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit
802 lmg %r0,%r15,SP_R0(%r15) # load gprs 0-15
803 tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ? 700 tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ?
804 jno 0f 701 jno 0f
805 stpt __LC_EXIT_TIMER 702 stpt __LC_EXIT_TIMER
8060: lpswe __LC_RETURN_MCCK_PSW # back to caller 703 mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
807mcck_done: 7040: lmg %r11,%r15,__PT_R11(%r11)
705 lpswe __LC_RETURN_MCCK_PSW
706
707mcck_panic:
708 lg %r14,__LC_PANIC_STACK
709 slgr %r14,%r15
710 srag %r14,%r14,PAGE_SHIFT
711 jz 0f
712 lg %r15,__LC_PANIC_STACK
7130: aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
714 j mcck_skip
808 715
809/* 716/*
810 * Restart interruption handler, kick starter for additional CPUs 717 * Restart interruption handler, kick starter for additional CPUs
@@ -818,17 +725,18 @@ restart_base:
818 stck __LC_LAST_UPDATE_CLOCK 725 stck __LC_LAST_UPDATE_CLOCK
819 mvc __LC_LAST_UPDATE_TIMER(8),restart_vtime-restart_base(%r1) 726 mvc __LC_LAST_UPDATE_TIMER(8),restart_vtime-restart_base(%r1)
820 mvc __LC_EXIT_TIMER(8),restart_vtime-restart_base(%r1) 727 mvc __LC_EXIT_TIMER(8),restart_vtime-restart_base(%r1)
821 lg %r15,__LC_SAVE_AREA+120 # load ksp 728 lghi %r10,__LC_GPREGS_SAVE_AREA
729 lg %r15,120(%r10) # load ksp
822 lghi %r10,__LC_CREGS_SAVE_AREA 730 lghi %r10,__LC_CREGS_SAVE_AREA
823 lctlg %c0,%c15,0(%r10) # get new ctl regs 731 lctlg %c0,%c15,0(%r10) # get new ctl regs
824 lghi %r10,__LC_AREGS_SAVE_AREA 732 lghi %r10,__LC_AREGS_SAVE_AREA
825 lam %a0,%a15,0(%r10) 733 lam %a0,%a15,0(%r10)
826 lmg %r6,%r15,__SF_GPRS(%r15) # load registers from clone 734 lmg %r6,%r15,__SF_GPRS(%r15)# load registers from clone
827 lg %r1,__LC_THREAD_INFO 735 lg %r1,__LC_THREAD_INFO
828 mvc __LC_USER_TIMER(8),__TI_user_timer(%r1) 736 mvc __LC_USER_TIMER(8),__TI_user_timer(%r1)
829 mvc __LC_SYSTEM_TIMER(8),__TI_system_timer(%r1) 737 mvc __LC_SYSTEM_TIMER(8),__TI_system_timer(%r1)
830 xc __LC_STEAL_TIMER(8),__LC_STEAL_TIMER 738 xc __LC_STEAL_TIMER(8),__LC_STEAL_TIMER
831 stosm __SF_EMPTY(%r15),0x04 # now we can turn dat on 739 ssm __LC_PGM_NEW_PSW # turn dat on, keep irqs off
832 brasl %r14,start_secondary 740 brasl %r14,start_secondary
833 .align 8 741 .align 8
834restart_vtime: 742restart_vtime:
@@ -852,16 +760,16 @@ restart_go:
852# PSW restart interrupt handler 760# PSW restart interrupt handler
853# 761#
854ENTRY(psw_restart_int_handler) 762ENTRY(psw_restart_int_handler)
855 stg %r15,__LC_SAVE_AREA+120(%r0) # save r15 763 stg %r15,__LC_SAVE_AREA_RESTART
856 larl %r15,restart_stack # load restart stack 764 larl %r15,restart_stack # load restart stack
857 lg %r15,0(%r15) 765 lg %r15,0(%r15)
858 aghi %r15,-SP_SIZE # make room for pt_regs 766 aghi %r15,-__PT_SIZE # create pt_regs on stack
859 stmg %r0,%r14,SP_R0(%r15) # store gprs %r0-%r14 to stack 767 stmg %r0,%r14,__PT_R0(%r15)
860 mvc SP_R15(8,%r15),__LC_SAVE_AREA+120(%r0)# store saved %r15 to stack 768 mvc __PT_R15(8,%r15),__LC_SAVE_AREA_RESTART
861 mvc SP_PSW(16,%r15),__LC_RST_OLD_PSW(%r0)# store restart old psw 769 mvc __PT_PSW(16,%r15),__LC_RST_OLD_PSW # store restart old psw
862 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) # set backchain to 0 770 aghi %r15,-STACK_FRAME_OVERHEAD
771 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
863 brasl %r14,do_restart 772 brasl %r14,do_restart
864
865 larl %r14,restart_psw_crash # load disabled wait PSW if 773 larl %r14,restart_psw_crash # load disabled wait PSW if
866 lpswe 0(%r14) # do_restart returns 774 lpswe 0(%r14) # do_restart returns
867 .align 8 775 .align 8
@@ -877,172 +785,153 @@ restart_psw_crash:
877 * Setup a pt_regs so that show_trace can provide a good call trace. 785 * Setup a pt_regs so that show_trace can provide a good call trace.
878 */ 786 */
879stack_overflow: 787stack_overflow:
880 lg %r15,__LC_PANIC_STACK # change to panic stack 788 lg %r11,__LC_PANIC_STACK # change to panic stack
881 aghi %r15,-SP_SIZE 789 aghi %r11,-__PT_SIZE # create pt_regs
882 mvc SP_PSW(16,%r15),0(%r12) # move user PSW to stack 790 stmg %r0,%r7,__PT_R0(%r11)
883 stmg %r0,%r10,SP_R0(%r15) # store gprs %r0-%r10 to kernel stack 791 stmg %r8,%r9,__PT_PSW(%r11)
884 la %r1,__LC_SAVE_AREA 792 mvc __PT_R8(64,%r11),0(%r14)
885 chi %r12,__LC_SVC_OLD_PSW 793 stg %r10,__PT_ORIG_GPR2(%r11) # store last break to orig_gpr2
886 je 0f 794 lgr %r15,%r11
887 chi %r12,__LC_PGM_OLD_PSW 795 aghi %r15,-STACK_FRAME_OVERHEAD
888 je 0f 796 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
889 la %r1,__LC_SAVE_AREA+40 797 lgr %r2,%r11 # pass pointer to pt_regs
8900: mvc SP_R11(40,%r15),0(%r1) # move %r11-%r15 to stack
891 mvc SP_ARGS(8,%r15),__LC_LAST_BREAK
892 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) # clear back chain
893 la %r2,SP_PTREGS(%r15) # load pt_regs
894 jg kernel_stack_overflow 798 jg kernel_stack_overflow
895#endif 799#endif
896 800
897cleanup_table_system_call: 801 .align 8
898 .quad system_call, sysc_do_svc 802cleanup_table:
899cleanup_table_sysc_tif: 803 .quad system_call
900 .quad sysc_tif, sysc_restore 804 .quad sysc_do_svc
901cleanup_table_sysc_restore: 805 .quad sysc_tif
902 .quad sysc_restore, sysc_done 806 .quad sysc_restore
903cleanup_table_io_tif: 807 .quad sysc_done
904 .quad io_tif, io_restore 808 .quad io_tif
905cleanup_table_io_restore: 809 .quad io_restore
906 .quad io_restore, io_done 810 .quad io_done
907 811
908cleanup_critical: 812cleanup_critical:
909 clc 8(8,%r12),BASED(cleanup_table_system_call) 813 clg %r9,BASED(cleanup_table) # system_call
910 jl 0f 814 jl 0f
911 clc 8(8,%r12),BASED(cleanup_table_system_call+8) 815 clg %r9,BASED(cleanup_table+8) # sysc_do_svc
912 jl cleanup_system_call 816 jl cleanup_system_call
9130: 817 clg %r9,BASED(cleanup_table+16) # sysc_tif
914 clc 8(8,%r12),BASED(cleanup_table_sysc_tif)
915 jl 0f 818 jl 0f
916 clc 8(8,%r12),BASED(cleanup_table_sysc_tif+8) 819 clg %r9,BASED(cleanup_table+24) # sysc_restore
917 jl cleanup_sysc_tif 820 jl cleanup_sysc_tif
9180: 821 clg %r9,BASED(cleanup_table+32) # sysc_done
919 clc 8(8,%r12),BASED(cleanup_table_sysc_restore)
920 jl 0f
921 clc 8(8,%r12),BASED(cleanup_table_sysc_restore+8)
922 jl cleanup_sysc_restore 822 jl cleanup_sysc_restore
9230: 823 clg %r9,BASED(cleanup_table+40) # io_tif
924 clc 8(8,%r12),BASED(cleanup_table_io_tif)
925 jl 0f 824 jl 0f
926 clc 8(8,%r12),BASED(cleanup_table_io_tif+8) 825 clg %r9,BASED(cleanup_table+48) # io_restore
927 jl cleanup_io_tif 826 jl cleanup_io_tif
9280: 827 clg %r9,BASED(cleanup_table+56) # io_done
929 clc 8(8,%r12),BASED(cleanup_table_io_restore)
930 jl 0f
931 clc 8(8,%r12),BASED(cleanup_table_io_restore+8)
932 jl cleanup_io_restore 828 jl cleanup_io_restore
9330: 8290: br %r14
934 br %r14 830
935 831
936cleanup_system_call: 832cleanup_system_call:
937 mvc __LC_RETURN_PSW(16),0(%r12) 833 # check if stpt has been executed
938 clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+8) 834 clg %r9,BASED(cleanup_system_call_insn)
939 jh 0f 835 jh 0f
940 mvc __LC_SYNC_ENTER_TIMER(8),__LC_MCCK_ENTER_TIMER
941 cghi %r12,__LC_MCK_OLD_PSW
942 je 0f
943 mvc __LC_SYNC_ENTER_TIMER(8),__LC_ASYNC_ENTER_TIMER 836 mvc __LC_SYNC_ENTER_TIMER(8),__LC_ASYNC_ENTER_TIMER
9440: cghi %r12,__LC_MCK_OLD_PSW 837 cghi %r11,__LC_SAVE_AREA_ASYNC
945 la %r12,__LC_SAVE_AREA+80
946 je 0f 838 je 0f
947 la %r12,__LC_SAVE_AREA+40 839 mvc __LC_SYNC_ENTER_TIMER(8),__LC_MCCK_ENTER_TIMER
9480: clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+16) 8400: # check if stmg has been executed
949 jhe cleanup_vtime 841 clg %r9,BASED(cleanup_system_call_insn+8)
950 clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn)
951 jh 0f 842 jh 0f
952 mvc __LC_SAVE_AREA(40),0(%r12) 843 mvc __LC_SAVE_AREA_SYNC(64),0(%r11)
9530: lg %r15,__LC_KERNEL_STACK # problem state -> load ksp 8440: # check if base register setup + TIF bit load has been done
954 aghi %r15,-SP_SIZE # make room for registers & psw 845 clg %r9,BASED(cleanup_system_call_insn+16)
955 stg %r15,32(%r12) 846 jhe 0f
956 stg %r11,0(%r12) 847 # set up saved registers r10 and r12
957 CREATE_STACK_FRAME __LC_SAVE_AREA 848 stg %r10,16(%r11) # r10 last break
958 mvc 8(8,%r12),__LC_THREAD_INFO 849 stg %r12,32(%r11) # r12 thread-info pointer
959 lg %r12,__LC_THREAD_INFO 8500: # check if the user time update has been done
960 mvc SP_PSW(16,%r15),__LC_SVC_OLD_PSW 851 clg %r9,BASED(cleanup_system_call_insn+24)
961 mvc SP_SVC_CODE(4,%r15),__LC_SVC_ILC 852 jh 0f
962 oi __TI_flags+7(%r12),_TIF_SYSCALL 853 lg %r15,__LC_EXIT_TIMER
963cleanup_vtime: 854 slg %r15,__LC_SYNC_ENTER_TIMER
964 clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+24) 855 alg %r15,__LC_USER_TIMER
965 jhe cleanup_stime 856 stg %r15,__LC_USER_TIMER
966 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER 8570: # check if the system time update has been done
967cleanup_stime: 858 clg %r9,BASED(cleanup_system_call_insn+32)
968 clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+32) 859 jh 0f
969 jh cleanup_update 860 lg %r15,__LC_LAST_UPDATE_TIMER
970 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 861 slg %r15,__LC_EXIT_TIMER
971cleanup_update: 862 alg %r15,__LC_SYSTEM_TIMER
863 stg %r15,__LC_SYSTEM_TIMER
8640: # update accounting time stamp
972 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 865 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
973 srag %r12,%r11,23 866 # do LAST_BREAK
974 lg %r12,__LC_THREAD_INFO 867 lg %r9,16(%r11)
868 srag %r9,%r9,23
975 jz 0f 869 jz 0f
976 stg %r11,__TI_last_break(%r12) 870 mvc __TI_last_break(8,%r12),16(%r11)
9770: mvc __LC_RETURN_PSW+8(8),BASED(cleanup_table_system_call+8) 8710: # set up saved register r11
978 la %r12,__LC_RETURN_PSW 872 lg %r15,__LC_KERNEL_STACK
873 aghi %r15,-__PT_SIZE
874 stg %r15,24(%r11) # r11 pt_regs pointer
875 # fill pt_regs
876 mvc __PT_R8(64,%r15),__LC_SAVE_AREA_SYNC
877 stmg %r0,%r7,__PT_R0(%r15)
878 mvc __PT_PSW(16,%r15),__LC_SVC_OLD_PSW
879 mvc __PT_INT_CODE(4,%r15),__LC_SVC_ILC
880 # setup saved register r15
881 aghi %r15,-STACK_FRAME_OVERHEAD
882 stg %r15,56(%r11) # r15 stack pointer
883 # set new psw address and exit
884 larl %r9,sysc_do_svc
979 br %r14 885 br %r14
980cleanup_system_call_insn: 886cleanup_system_call_insn:
981 .quad sysc_saveall
982 .quad system_call 887 .quad system_call
983 .quad sysc_vtime 888 .quad sysc_stmg
984 .quad sysc_stime 889 .quad sysc_per
985 .quad sysc_update 890 .quad sysc_vtime+18
891 .quad sysc_vtime+42
986 892
987cleanup_sysc_tif: 893cleanup_sysc_tif:
988 mvc __LC_RETURN_PSW(8),0(%r12) 894 larl %r9,sysc_tif
989 mvc __LC_RETURN_PSW+8(8),BASED(cleanup_table_sysc_tif)
990 la %r12,__LC_RETURN_PSW
991 br %r14 895 br %r14
992 896
993cleanup_sysc_restore: 897cleanup_sysc_restore:
994 clc 8(8,%r12),BASED(cleanup_sysc_restore_insn) 898 clg %r9,BASED(cleanup_sysc_restore_insn)
995 je 2f
996 clc 8(8,%r12),BASED(cleanup_sysc_restore_insn+8)
997 jhe 0f
998 mvc __LC_EXIT_TIMER(8),__LC_MCCK_ENTER_TIMER
999 cghi %r12,__LC_MCK_OLD_PSW
1000 je 0f 899 je 0f
1001 mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER 900 lg %r9,24(%r11) # get saved pointer to pt_regs
10020: mvc __LC_RETURN_PSW(16),SP_PSW(%r15) 901 mvc __LC_RETURN_PSW(16),__PT_PSW(%r9)
1003 cghi %r12,__LC_MCK_OLD_PSW 902 mvc 0(64,%r11),__PT_R8(%r9)
1004 la %r12,__LC_SAVE_AREA+80 903 lmg %r0,%r7,__PT_R0(%r9)
1005 je 1f 9040: lmg %r8,%r9,__LC_RETURN_PSW
1006 la %r12,__LC_SAVE_AREA+40
10071: mvc 0(40,%r12),SP_R11(%r15)
1008 lmg %r0,%r10,SP_R0(%r15)
1009 lg %r15,SP_R15(%r15)
10102: la %r12,__LC_RETURN_PSW
1011 br %r14 905 br %r14
1012cleanup_sysc_restore_insn: 906cleanup_sysc_restore_insn:
1013 .quad sysc_done - 4 907 .quad sysc_done - 4
1014 .quad sysc_done - 16
1015 908
1016cleanup_io_tif: 909cleanup_io_tif:
1017 mvc __LC_RETURN_PSW(8),0(%r12) 910 larl %r9,io_tif
1018 mvc __LC_RETURN_PSW+8(8),BASED(cleanup_table_io_tif)
1019 la %r12,__LC_RETURN_PSW
1020 br %r14 911 br %r14
1021 912
1022cleanup_io_restore: 913cleanup_io_restore:
1023 clc 8(8,%r12),BASED(cleanup_io_restore_insn) 914 clg %r9,BASED(cleanup_io_restore_insn)
1024 je 1f 915 je 0f
1025 clc 8(8,%r12),BASED(cleanup_io_restore_insn+8) 916 lg %r9,24(%r11) # get saved r11 pointer to pt_regs
1026 jhe 0f 917 mvc __LC_RETURN_PSW(16),__PT_PSW(%r9)
1027 mvc __LC_EXIT_TIMER(8),__LC_MCCK_ENTER_TIMER 918 ni __LC_RETURN_PSW+1,0xfd # clear wait state bit
10280: mvc __LC_RETURN_PSW(16),SP_PSW(%r15) 919 mvc 0(64,%r11),__PT_R8(%r9)
1029 mvc __LC_SAVE_AREA+80(40),SP_R11(%r15) 920 lmg %r0,%r7,__PT_R0(%r9)
1030 lmg %r0,%r10,SP_R0(%r15) 9210: lmg %r8,%r9,__LC_RETURN_PSW
1031 lg %r15,SP_R15(%r15)
10321: la %r12,__LC_RETURN_PSW
1033 br %r14 922 br %r14
1034cleanup_io_restore_insn: 923cleanup_io_restore_insn:
1035 .quad io_done - 4 924 .quad io_done - 4
1036 .quad io_done - 16
1037 925
1038/* 926/*
1039 * Integer constants 927 * Integer constants
1040 */ 928 */
1041 .align 4 929 .align 8
1042.Lcritical_start: 930.Lcritical_start:
1043 .quad __critical_start 931 .quad __critical_start
1044.Lcritical_end: 932.Lcritical_length:
1045 .quad __critical_end 933 .quad __critical_end - __critical_start
934
1046 935
1047#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE) 936#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE)
1048/* 937/*
@@ -1054,6 +943,7 @@ ENTRY(sie64a)
1054 stmg %r6,%r14,__SF_GPRS(%r15) # save kernel registers 943 stmg %r6,%r14,__SF_GPRS(%r15) # save kernel registers
1055 stg %r2,__SF_EMPTY(%r15) # save control block pointer 944 stg %r2,__SF_EMPTY(%r15) # save control block pointer
1056 stg %r3,__SF_EMPTY+8(%r15) # save guest register save area 945 stg %r3,__SF_EMPTY+8(%r15) # save guest register save area
946 xc __SF_EMPTY+16(8,%r15),__SF_EMPTY+16(%r15) # host id == 0
1057 lmg %r0,%r13,0(%r3) # load guest gprs 0-13 947 lmg %r0,%r13,0(%r3) # load guest gprs 0-13
1058 lg %r14,__LC_THREAD_INFO # pointer thread_info struct 948 lg %r14,__LC_THREAD_INFO # pointer thread_info struct
1059 oi __TI_flags+6(%r14),_TIF_SIE>>8 949 oi __TI_flags+6(%r14),_TIF_SIE>>8
@@ -1070,7 +960,7 @@ sie_gmap:
1070 SPP __SF_EMPTY(%r15) # set guest id 960 SPP __SF_EMPTY(%r15) # set guest id
1071 sie 0(%r14) 961 sie 0(%r14)
1072sie_done: 962sie_done:
1073 SPP __LC_CMF_HPP # set host id 963 SPP __SF_EMPTY+16(%r15) # set host id
1074 lg %r14,__LC_THREAD_INFO # pointer thread_info struct 964 lg %r14,__LC_THREAD_INFO # pointer thread_info struct
1075sie_exit: 965sie_exit:
1076 lctlg %c1,%c1,__LC_USER_ASCE # load primary asce 966 lctlg %c1,%c1,__LC_USER_ASCE # load primary asce
@@ -1093,8 +983,10 @@ sie_fault:
1093 .align 8 983 .align 8
1094.Lsie_loop: 984.Lsie_loop:
1095 .quad sie_loop 985 .quad sie_loop
1096.Lsie_done: 986.Lsie_length:
1097 .quad sie_done 987 .quad sie_done - sie_loop
988.Lhost_id:
989 .quad 0
1098 990
1099 .section __ex_table,"a" 991 .section __ex_table,"a"
1100 .quad sie_loop,sie_fault 992 .quad sie_loop,sie_fault
diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S
index 900068d2bf92..c27a0727f930 100644
--- a/arch/s390/kernel/head.S
+++ b/arch/s390/kernel/head.S
@@ -329,8 +329,8 @@ iplstart:
329# 329#
330# reset files in VM reader 330# reset files in VM reader
331# 331#
332 stidp __LC_SAVE_AREA # store cpuid 332 stidp __LC_SAVE_AREA_SYNC # store cpuid
333 tm __LC_SAVE_AREA,0xff # running VM ? 333 tm __LC_SAVE_AREA_SYNC,0xff# running VM ?
334 bno .Lnoreset 334 bno .Lnoreset
335 la %r2,.Lreset 335 la %r2,.Lreset
336 lhi %r3,26 336 lhi %r3,26
diff --git a/arch/s390/kernel/machine_kexec.c b/arch/s390/kernel/machine_kexec.c
index 3cd0f25ab015..47b168fb29c4 100644
--- a/arch/s390/kernel/machine_kexec.c
+++ b/arch/s390/kernel/machine_kexec.c
@@ -208,6 +208,7 @@ void machine_kexec_cleanup(struct kimage *image)
208void arch_crash_save_vmcoreinfo(void) 208void arch_crash_save_vmcoreinfo(void)
209{ 209{
210 VMCOREINFO_SYMBOL(lowcore_ptr); 210 VMCOREINFO_SYMBOL(lowcore_ptr);
211 VMCOREINFO_SYMBOL(high_memory);
211 VMCOREINFO_LENGTH(lowcore_ptr, NR_CPUS); 212 VMCOREINFO_LENGTH(lowcore_ptr, NR_CPUS);
212} 213}
213 214
diff --git a/arch/s390/kernel/mem_detect.c b/arch/s390/kernel/mem_detect.c
index 19b4568f4cee..22d502e885ed 100644
--- a/arch/s390/kernel/mem_detect.c
+++ b/arch/s390/kernel/mem_detect.c
@@ -64,70 +64,82 @@ void detect_memory_layout(struct mem_chunk chunk[])
64EXPORT_SYMBOL(detect_memory_layout); 64EXPORT_SYMBOL(detect_memory_layout);
65 65
66/* 66/*
67 * Move memory chunks array from index "from" to index "to"
68 */
69static void mem_chunk_move(struct mem_chunk chunk[], int to, int from)
70{
71 int cnt = MEMORY_CHUNKS - to;
72
73 memmove(&chunk[to], &chunk[from], cnt * sizeof(struct mem_chunk));
74}
75
76/*
77 * Initialize memory chunk
78 */
79static void mem_chunk_init(struct mem_chunk *chunk, unsigned long addr,
80 unsigned long size, int type)
81{
82 chunk->type = type;
83 chunk->addr = addr;
84 chunk->size = size;
85}
86
87/*
67 * Create memory hole with given address, size, and type 88 * Create memory hole with given address, size, and type
68 */ 89 */
69void create_mem_hole(struct mem_chunk chunks[], unsigned long addr, 90void create_mem_hole(struct mem_chunk chunk[], unsigned long addr,
70 unsigned long size, int type) 91 unsigned long size, int type)
71{ 92{
72 unsigned long start, end, new_size; 93 unsigned long lh_start, lh_end, lh_size, ch_start, ch_end, ch_size;
73 int i; 94 int i, ch_type;
74 95
75 for (i = 0; i < MEMORY_CHUNKS; i++) { 96 for (i = 0; i < MEMORY_CHUNKS; i++) {
76 if (chunks[i].size == 0) 97 if (chunk[i].size == 0)
77 continue;
78 if (addr + size < chunks[i].addr)
79 continue;
80 if (addr >= chunks[i].addr + chunks[i].size)
81 continue; 98 continue;
82 start = max(addr, chunks[i].addr); 99
83 end = min(addr + size, chunks[i].addr + chunks[i].size); 100 /* Define chunk properties */
84 new_size = end - start; 101 ch_start = chunk[i].addr;
85 if (new_size == 0) 102 ch_size = chunk[i].size;
86 continue; 103 ch_end = ch_start + ch_size - 1;
87 if (start == chunks[i].addr && 104 ch_type = chunk[i].type;
88 end == chunks[i].addr + chunks[i].size) { 105
89 /* Remove chunk */ 106 /* Is memory chunk hit by memory hole? */
90 chunks[i].type = type; 107 if (addr + size <= ch_start)
91 } else if (start == chunks[i].addr) { 108 continue; /* No: memory hole in front of chunk */
92 /* Make chunk smaller at start */ 109 if (addr > ch_end)
93 if (i >= MEMORY_CHUNKS - 1) 110 continue; /* No: memory hole after chunk */
94 panic("Unable to create memory hole"); 111
95 memmove(&chunks[i + 1], &chunks[i], 112 /* Yes: Define local hole properties */
96 sizeof(struct mem_chunk) * 113 lh_start = max(addr, chunk[i].addr);
97 (MEMORY_CHUNKS - (i + 1))); 114 lh_end = min(addr + size - 1, ch_end);
98 chunks[i + 1].addr = chunks[i].addr + new_size; 115 lh_size = lh_end - lh_start + 1;
99 chunks[i + 1].size = chunks[i].size - new_size; 116
100 chunks[i].size = new_size; 117 if (lh_start == ch_start && lh_end == ch_end) {
101 chunks[i].type = type; 118 /* Hole covers complete memory chunk */
102 i += 1; 119 mem_chunk_init(&chunk[i], lh_start, lh_size, type);
103 } else if (end == chunks[i].addr + chunks[i].size) { 120 } else if (lh_end == ch_end) {
104 /* Make chunk smaller at end */ 121 /* Hole starts in memory chunk and convers chunk end */
105 if (i >= MEMORY_CHUNKS - 1) 122 mem_chunk_move(chunk, i + 1, i);
106 panic("Unable to create memory hole"); 123 mem_chunk_init(&chunk[i], ch_start, ch_size - lh_size,
107 memmove(&chunks[i + 1], &chunks[i], 124 ch_type);
108 sizeof(struct mem_chunk) * 125 mem_chunk_init(&chunk[i + 1], lh_start, lh_size, type);
109 (MEMORY_CHUNKS - (i + 1)));
110 chunks[i + 1].addr = start;
111 chunks[i + 1].size = new_size;
112 chunks[i + 1].type = type;
113 chunks[i].size -= new_size;
114 i += 1; 126 i += 1;
127 } else if (lh_start == ch_start) {
128 /* Hole ends in memory chunk */
129 mem_chunk_move(chunk, i + 1, i);
130 mem_chunk_init(&chunk[i], lh_start, lh_size, type);
131 mem_chunk_init(&chunk[i + 1], lh_end + 1,
132 ch_size - lh_size, ch_type);
133 break;
115 } else { 134 } else {
116 /* Create memory hole */ 135 /* Hole splits memory chunk */
117 if (i >= MEMORY_CHUNKS - 2) 136 mem_chunk_move(chunk, i + 2, i);
118 panic("Unable to create memory hole"); 137 mem_chunk_init(&chunk[i], ch_start,
119 memmove(&chunks[i + 2], &chunks[i], 138 lh_start - ch_start, ch_type);
120 sizeof(struct mem_chunk) * 139 mem_chunk_init(&chunk[i + 1], lh_start, lh_size, type);
121 (MEMORY_CHUNKS - (i + 2))); 140 mem_chunk_init(&chunk[i + 2], lh_end + 1,
122 chunks[i + 1].addr = addr; 141 ch_end - lh_end, ch_type);
123 chunks[i + 1].size = size; 142 break;
124 chunks[i + 1].type = type;
125 chunks[i + 2].addr = addr + size;
126 chunks[i + 2].size =
127 chunks[i].addr + chunks[i].size - (addr + size);
128 chunks[i + 2].type = chunks[i].type;
129 chunks[i].size = addr - chunks[i].addr;
130 i += 2;
131 } 143 }
132 } 144 }
133} 145}
diff --git a/arch/s390/kernel/reipl64.S b/arch/s390/kernel/reipl64.S
index 732a793ec53a..36b32658fb24 100644
--- a/arch/s390/kernel/reipl64.S
+++ b/arch/s390/kernel/reipl64.S
@@ -17,11 +17,11 @@
17# 17#
18ENTRY(store_status) 18ENTRY(store_status)
19 /* Save register one and load save area base */ 19 /* Save register one and load save area base */
20 stg %r1,__LC_SAVE_AREA+120(%r0) 20 stg %r1,__LC_SAVE_AREA_RESTART
21 lghi %r1,SAVE_AREA_BASE 21 lghi %r1,SAVE_AREA_BASE
22 /* General purpose registers */ 22 /* General purpose registers */
23 stmg %r0,%r15,__LC_GPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) 23 stmg %r0,%r15,__LC_GPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
24 lg %r2,__LC_SAVE_AREA+120(%r0) 24 lg %r2,__LC_SAVE_AREA_RESTART
25 stg %r2,__LC_GPREGS_SAVE_AREA-SAVE_AREA_BASE+8(%r1) 25 stg %r2,__LC_GPREGS_SAVE_AREA-SAVE_AREA_BASE+8(%r1)
26 /* Control registers */ 26 /* Control registers */
27 stctg %c0,%c15,__LC_CREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) 27 stctg %c0,%c15,__LC_CREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index f11d1b037c50..354de0763eff 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -95,6 +95,15 @@ struct mem_chunk __initdata memory_chunk[MEMORY_CHUNKS];
95int __initdata memory_end_set; 95int __initdata memory_end_set;
96unsigned long __initdata memory_end; 96unsigned long __initdata memory_end;
97 97
98unsigned long VMALLOC_START;
99EXPORT_SYMBOL(VMALLOC_START);
100
101unsigned long VMALLOC_END;
102EXPORT_SYMBOL(VMALLOC_END);
103
104struct page *vmemmap;
105EXPORT_SYMBOL(vmemmap);
106
98/* An array with a pointer to the lowcore of every CPU. */ 107/* An array with a pointer to the lowcore of every CPU. */
99struct _lowcore *lowcore_ptr[NR_CPUS]; 108struct _lowcore *lowcore_ptr[NR_CPUS];
100EXPORT_SYMBOL(lowcore_ptr); 109EXPORT_SYMBOL(lowcore_ptr);
@@ -278,6 +287,15 @@ static int __init early_parse_mem(char *p)
278} 287}
279early_param("mem", early_parse_mem); 288early_param("mem", early_parse_mem);
280 289
290static int __init parse_vmalloc(char *arg)
291{
292 if (!arg)
293 return -EINVAL;
294 VMALLOC_END = (memparse(arg, &arg) + PAGE_SIZE - 1) & PAGE_MASK;
295 return 0;
296}
297early_param("vmalloc", parse_vmalloc);
298
281unsigned int user_mode = HOME_SPACE_MODE; 299unsigned int user_mode = HOME_SPACE_MODE;
282EXPORT_SYMBOL_GPL(user_mode); 300EXPORT_SYMBOL_GPL(user_mode);
283 301
@@ -383,7 +401,6 @@ setup_lowcore(void)
383 __ctl_set_bit(14, 29); 401 __ctl_set_bit(14, 29);
384 } 402 }
385#else 403#else
386 lc->cmf_hpp = -1ULL;
387 lc->vdso_per_cpu_data = (unsigned long) &lc->paste[0]; 404 lc->vdso_per_cpu_data = (unsigned long) &lc->paste[0];
388#endif 405#endif
389 lc->sync_enter_timer = S390_lowcore.sync_enter_timer; 406 lc->sync_enter_timer = S390_lowcore.sync_enter_timer;
@@ -479,8 +496,7 @@ EXPORT_SYMBOL_GPL(real_memory_size);
479 496
480static void __init setup_memory_end(void) 497static void __init setup_memory_end(void)
481{ 498{
482 unsigned long memory_size; 499 unsigned long vmax, vmalloc_size, tmp;
483 unsigned long max_mem;
484 int i; 500 int i;
485 501
486 502
@@ -490,12 +506,9 @@ static void __init setup_memory_end(void)
490 memory_end_set = 1; 506 memory_end_set = 1;
491 } 507 }
492#endif 508#endif
493 memory_size = 0; 509 real_memory_size = 0;
494 memory_end &= PAGE_MASK; 510 memory_end &= PAGE_MASK;
495 511
496 max_mem = memory_end ? min(VMEM_MAX_PHYS, memory_end) : VMEM_MAX_PHYS;
497 memory_end = min(max_mem, memory_end);
498
499 /* 512 /*
500 * Make sure all chunks are MAX_ORDER aligned so we don't need the 513 * Make sure all chunks are MAX_ORDER aligned so we don't need the
501 * extra checks that HOLES_IN_ZONE would require. 514 * extra checks that HOLES_IN_ZONE would require.
@@ -515,23 +528,48 @@ static void __init setup_memory_end(void)
515 chunk->addr = start; 528 chunk->addr = start;
516 chunk->size = end - start; 529 chunk->size = end - start;
517 } 530 }
531 real_memory_size = max(real_memory_size,
532 chunk->addr + chunk->size);
518 } 533 }
519 534
535 /* Choose kernel address space layout: 2, 3, or 4 levels. */
536#ifdef CONFIG_64BIT
537 vmalloc_size = VMALLOC_END ?: 128UL << 30;
538 tmp = (memory_end ?: real_memory_size) / PAGE_SIZE;
539 tmp = tmp * (sizeof(struct page) + PAGE_SIZE) + vmalloc_size;
540 if (tmp <= (1UL << 42))
541 vmax = 1UL << 42; /* 3-level kernel page table */
542 else
543 vmax = 1UL << 53; /* 4-level kernel page table */
544#else
545 vmalloc_size = VMALLOC_END ?: 96UL << 20;
546 vmax = 1UL << 31; /* 2-level kernel page table */
547#endif
548 /* vmalloc area is at the end of the kernel address space. */
549 VMALLOC_END = vmax;
550 VMALLOC_START = vmax - vmalloc_size;
551
552 /* Split remaining virtual space between 1:1 mapping & vmemmap array */
553 tmp = VMALLOC_START / (PAGE_SIZE + sizeof(struct page));
554 tmp = VMALLOC_START - tmp * sizeof(struct page);
555 tmp &= ~((vmax >> 11) - 1); /* align to page table level */
556 tmp = min(tmp, 1UL << MAX_PHYSMEM_BITS);
557 vmemmap = (struct page *) tmp;
558
559 /* Take care that memory_end is set and <= vmemmap */
560 memory_end = min(memory_end ?: real_memory_size, tmp);
561
562 /* Fixup memory chunk array to fit into 0..memory_end */
520 for (i = 0; i < MEMORY_CHUNKS; i++) { 563 for (i = 0; i < MEMORY_CHUNKS; i++) {
521 struct mem_chunk *chunk = &memory_chunk[i]; 564 struct mem_chunk *chunk = &memory_chunk[i];
522 565
523 real_memory_size = max(real_memory_size, 566 if (chunk->addr >= memory_end) {
524 chunk->addr + chunk->size);
525 if (chunk->addr >= max_mem) {
526 memset(chunk, 0, sizeof(*chunk)); 567 memset(chunk, 0, sizeof(*chunk));
527 continue; 568 continue;
528 } 569 }
529 if (chunk->addr + chunk->size > max_mem) 570 if (chunk->addr + chunk->size > memory_end)
530 chunk->size = max_mem - chunk->addr; 571 chunk->size = memory_end - chunk->addr;
531 memory_size = max(memory_size, chunk->addr + chunk->size);
532 } 572 }
533 if (!memory_end)
534 memory_end = memory_size;
535} 573}
536 574
537void *restart_stack __attribute__((__section__(".data"))); 575void *restart_stack __attribute__((__section__(".data")));
@@ -655,7 +693,6 @@ static int __init verify_crash_base(unsigned long crash_base,
655static void __init reserve_kdump_bootmem(unsigned long addr, unsigned long size, 693static void __init reserve_kdump_bootmem(unsigned long addr, unsigned long size,
656 int type) 694 int type)
657{ 695{
658
659 create_mem_hole(memory_chunk, addr, size, type); 696 create_mem_hole(memory_chunk, addr, size, type);
660} 697}
661 698
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c
index 7f6f9f354545..a8ba840294ff 100644
--- a/arch/s390/kernel/signal.c
+++ b/arch/s390/kernel/signal.c
@@ -302,9 +302,13 @@ static int setup_frame(int sig, struct k_sigaction *ka,
302 302
303 /* We forgot to include these in the sigcontext. 303 /* We forgot to include these in the sigcontext.
304 To avoid breaking binary compatibility, they are passed as args. */ 304 To avoid breaking binary compatibility, they are passed as args. */
305 regs->gprs[4] = current->thread.trap_no; 305 if (sig == SIGSEGV || sig == SIGBUS || sig == SIGILL ||
306 regs->gprs[5] = current->thread.prot_addr; 306 sig == SIGTRAP || sig == SIGFPE) {
307 regs->gprs[6] = task_thread_info(current)->last_break; 307 /* set extra registers only for synchronous signals */
308 regs->gprs[4] = regs->int_code & 127;
309 regs->gprs[5] = regs->int_parm_long;
310 regs->gprs[6] = task_thread_info(current)->last_break;
311 }
308 312
309 /* Place signal number on stack to allow backtrace from handler. */ 313 /* Place signal number on stack to allow backtrace from handler. */
310 if (__put_user(regs->gprs[2], (int __user *) &frame->signo)) 314 if (__put_user(regs->gprs[2], (int __user *) &frame->signo))
@@ -434,13 +438,13 @@ void do_signal(struct pt_regs *regs)
434 * call information. 438 * call information.
435 */ 439 */
436 current_thread_info()->system_call = 440 current_thread_info()->system_call =
437 test_thread_flag(TIF_SYSCALL) ? regs->svc_code : 0; 441 test_thread_flag(TIF_SYSCALL) ? regs->int_code : 0;
438 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 442 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
439 443
440 if (signr > 0) { 444 if (signr > 0) {
441 /* Whee! Actually deliver the signal. */ 445 /* Whee! Actually deliver the signal. */
442 if (current_thread_info()->system_call) { 446 if (current_thread_info()->system_call) {
443 regs->svc_code = current_thread_info()->system_call; 447 regs->int_code = current_thread_info()->system_call;
444 /* Check for system call restarting. */ 448 /* Check for system call restarting. */
445 switch (regs->gprs[2]) { 449 switch (regs->gprs[2]) {
446 case -ERESTART_RESTARTBLOCK: 450 case -ERESTART_RESTARTBLOCK:
@@ -457,7 +461,7 @@ void do_signal(struct pt_regs *regs)
457 regs->gprs[2] = regs->orig_gpr2; 461 regs->gprs[2] = regs->orig_gpr2;
458 regs->psw.addr = 462 regs->psw.addr =
459 __rewind_psw(regs->psw, 463 __rewind_psw(regs->psw,
460 regs->svc_code >> 16); 464 regs->int_code >> 16);
461 break; 465 break;
462 } 466 }
463 } 467 }
@@ -488,11 +492,11 @@ void do_signal(struct pt_regs *regs)
488 /* No handlers present - check for system call restart */ 492 /* No handlers present - check for system call restart */
489 clear_thread_flag(TIF_SYSCALL); 493 clear_thread_flag(TIF_SYSCALL);
490 if (current_thread_info()->system_call) { 494 if (current_thread_info()->system_call) {
491 regs->svc_code = current_thread_info()->system_call; 495 regs->int_code = current_thread_info()->system_call;
492 switch (regs->gprs[2]) { 496 switch (regs->gprs[2]) {
493 case -ERESTART_RESTARTBLOCK: 497 case -ERESTART_RESTARTBLOCK:
494 /* Restart with sys_restart_syscall */ 498 /* Restart with sys_restart_syscall */
495 regs->svc_code = __NR_restart_syscall; 499 regs->int_code = __NR_restart_syscall;
496 /* fallthrough */ 500 /* fallthrough */
497 case -ERESTARTNOHAND: 501 case -ERESTARTNOHAND:
498 case -ERESTARTSYS: 502 case -ERESTARTSYS:
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 66cca03c0282..2398ce6b15ae 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -69,9 +69,7 @@ enum s390_cpu_state {
69}; 69};
70 70
71DEFINE_MUTEX(smp_cpu_state_mutex); 71DEFINE_MUTEX(smp_cpu_state_mutex);
72int smp_cpu_polarization[NR_CPUS];
73static int smp_cpu_state[NR_CPUS]; 72static int smp_cpu_state[NR_CPUS];
74static int cpu_management;
75 73
76static DEFINE_PER_CPU(struct cpu, cpu_devices); 74static DEFINE_PER_CPU(struct cpu, cpu_devices);
77 75
@@ -149,29 +147,59 @@ void smp_switch_to_ipl_cpu(void (*func)(void *), void *data)
149 sp -= sizeof(struct pt_regs); 147 sp -= sizeof(struct pt_regs);
150 regs = (struct pt_regs *) sp; 148 regs = (struct pt_regs *) sp;
151 memcpy(&regs->gprs, &current_lc->gpregs_save_area, sizeof(regs->gprs)); 149 memcpy(&regs->gprs, &current_lc->gpregs_save_area, sizeof(regs->gprs));
152 regs->psw = lc->psw_save_area; 150 regs->psw = current_lc->psw_save_area;
153 sp -= STACK_FRAME_OVERHEAD; 151 sp -= STACK_FRAME_OVERHEAD;
154 sf = (struct stack_frame *) sp; 152 sf = (struct stack_frame *) sp;
155 sf->back_chain = regs->gprs[15]; 153 sf->back_chain = 0;
156 smp_switch_to_cpu(func, data, sp, stap(), __cpu_logical_map[0]); 154 smp_switch_to_cpu(func, data, sp, stap(), __cpu_logical_map[0]);
157} 155}
158 156
157static void smp_stop_cpu(void)
158{
159 while (sigp(smp_processor_id(), sigp_stop) == sigp_busy)
160 cpu_relax();
161}
162
159void smp_send_stop(void) 163void smp_send_stop(void)
160{ 164{
161 int cpu, rc; 165 cpumask_t cpumask;
166 int cpu;
167 u64 end;
162 168
163 /* Disable all interrupts/machine checks */ 169 /* Disable all interrupts/machine checks */
164 __load_psw_mask(psw_kernel_bits | PSW_MASK_DAT); 170 __load_psw_mask(psw_kernel_bits | PSW_MASK_DAT);
165 trace_hardirqs_off(); 171 trace_hardirqs_off();
166 172
167 /* stop all processors */ 173 cpumask_copy(&cpumask, cpu_online_mask);
168 for_each_online_cpu(cpu) { 174 cpumask_clear_cpu(smp_processor_id(), &cpumask);
169 if (cpu == smp_processor_id()) 175
170 continue; 176 if (oops_in_progress) {
171 do { 177 /*
172 rc = sigp(cpu, sigp_stop); 178 * Give the other cpus the opportunity to complete
173 } while (rc == sigp_busy); 179 * outstanding interrupts before stopping them.
180 */
181 end = get_clock() + (1000000UL << 12);
182 for_each_cpu(cpu, &cpumask) {
183 set_bit(ec_stop_cpu, (unsigned long *)
184 &lowcore_ptr[cpu]->ext_call_fast);
185 while (sigp(cpu, sigp_emergency_signal) == sigp_busy &&
186 get_clock() < end)
187 cpu_relax();
188 }
189 while (get_clock() < end) {
190 for_each_cpu(cpu, &cpumask)
191 if (cpu_stopped(cpu))
192 cpumask_clear_cpu(cpu, &cpumask);
193 if (cpumask_empty(&cpumask))
194 break;
195 cpu_relax();
196 }
197 }
174 198
199 /* stop all processors */
200 for_each_cpu(cpu, &cpumask) {
201 while (sigp(cpu, sigp_stop) == sigp_busy)
202 cpu_relax();
175 while (!cpu_stopped(cpu)) 203 while (!cpu_stopped(cpu))
176 cpu_relax(); 204 cpu_relax();
177 } 205 }
@@ -187,7 +215,7 @@ static void do_ext_call_interrupt(unsigned int ext_int_code,
187{ 215{
188 unsigned long bits; 216 unsigned long bits;
189 217
190 if (ext_int_code == 0x1202) 218 if ((ext_int_code & 0xffff) == 0x1202)
191 kstat_cpu(smp_processor_id()).irqs[EXTINT_EXC]++; 219 kstat_cpu(smp_processor_id()).irqs[EXTINT_EXC]++;
192 else 220 else
193 kstat_cpu(smp_processor_id()).irqs[EXTINT_EMS]++; 221 kstat_cpu(smp_processor_id()).irqs[EXTINT_EMS]++;
@@ -196,6 +224,9 @@ static void do_ext_call_interrupt(unsigned int ext_int_code,
196 */ 224 */
197 bits = xchg(&S390_lowcore.ext_call_fast, 0); 225 bits = xchg(&S390_lowcore.ext_call_fast, 0);
198 226
227 if (test_bit(ec_stop_cpu, &bits))
228 smp_stop_cpu();
229
199 if (test_bit(ec_schedule, &bits)) 230 if (test_bit(ec_schedule, &bits))
200 scheduler_ipi(); 231 scheduler_ipi();
201 232
@@ -204,6 +235,7 @@ static void do_ext_call_interrupt(unsigned int ext_int_code,
204 235
205 if (test_bit(ec_call_function_single, &bits)) 236 if (test_bit(ec_call_function_single, &bits))
206 generic_smp_call_function_single_interrupt(); 237 generic_smp_call_function_single_interrupt();
238
207} 239}
208 240
209/* 241/*
@@ -369,7 +401,7 @@ static int smp_rescan_cpus_sigp(cpumask_t avail)
369 if (cpu_known(cpu_id)) 401 if (cpu_known(cpu_id))
370 continue; 402 continue;
371 __cpu_logical_map[logical_cpu] = cpu_id; 403 __cpu_logical_map[logical_cpu] = cpu_id;
372 smp_cpu_polarization[logical_cpu] = POLARIZATION_UNKNWN; 404 cpu_set_polarization(logical_cpu, POLARIZATION_UNKNOWN);
373 if (!cpu_stopped(logical_cpu)) 405 if (!cpu_stopped(logical_cpu))
374 continue; 406 continue;
375 set_cpu_present(logical_cpu, true); 407 set_cpu_present(logical_cpu, true);
@@ -403,7 +435,7 @@ static int smp_rescan_cpus_sclp(cpumask_t avail)
403 if (cpu_known(cpu_id)) 435 if (cpu_known(cpu_id))
404 continue; 436 continue;
405 __cpu_logical_map[logical_cpu] = cpu_id; 437 __cpu_logical_map[logical_cpu] = cpu_id;
406 smp_cpu_polarization[logical_cpu] = POLARIZATION_UNKNWN; 438 cpu_set_polarization(logical_cpu, POLARIZATION_UNKNOWN);
407 set_cpu_present(logical_cpu, true); 439 set_cpu_present(logical_cpu, true);
408 if (cpu >= info->configured) 440 if (cpu >= info->configured)
409 smp_cpu_state[logical_cpu] = CPU_STATE_STANDBY; 441 smp_cpu_state[logical_cpu] = CPU_STATE_STANDBY;
@@ -656,7 +688,7 @@ int __cpuinit __cpu_up(unsigned int cpu)
656 - sizeof(struct stack_frame)); 688 - sizeof(struct stack_frame));
657 memset(sf, 0, sizeof(struct stack_frame)); 689 memset(sf, 0, sizeof(struct stack_frame));
658 sf->gprs[9] = (unsigned long) sf; 690 sf->gprs[9] = (unsigned long) sf;
659 cpu_lowcore->save_area[15] = (unsigned long) sf; 691 cpu_lowcore->gpregs_save_area[15] = (unsigned long) sf;
660 __ctl_store(cpu_lowcore->cregs_save_area, 0, 15); 692 __ctl_store(cpu_lowcore->cregs_save_area, 0, 15);
661 atomic_inc(&init_mm.context.attach_count); 693 atomic_inc(&init_mm.context.attach_count);
662 asm volatile( 694 asm volatile(
@@ -806,7 +838,7 @@ void __init smp_prepare_boot_cpu(void)
806 S390_lowcore.percpu_offset = __per_cpu_offset[0]; 838 S390_lowcore.percpu_offset = __per_cpu_offset[0];
807 current_set[0] = current; 839 current_set[0] = current;
808 smp_cpu_state[0] = CPU_STATE_CONFIGURED; 840 smp_cpu_state[0] = CPU_STATE_CONFIGURED;
809 smp_cpu_polarization[0] = POLARIZATION_UNKNWN; 841 cpu_set_polarization(0, POLARIZATION_UNKNOWN);
810} 842}
811 843
812void __init smp_cpus_done(unsigned int max_cpus) 844void __init smp_cpus_done(unsigned int max_cpus)
@@ -868,7 +900,8 @@ static ssize_t cpu_configure_store(struct device *dev,
868 rc = sclp_cpu_deconfigure(__cpu_logical_map[cpu]); 900 rc = sclp_cpu_deconfigure(__cpu_logical_map[cpu]);
869 if (!rc) { 901 if (!rc) {
870 smp_cpu_state[cpu] = CPU_STATE_STANDBY; 902 smp_cpu_state[cpu] = CPU_STATE_STANDBY;
871 smp_cpu_polarization[cpu] = POLARIZATION_UNKNWN; 903 cpu_set_polarization(cpu, POLARIZATION_UNKNOWN);
904 topology_expect_change();
872 } 905 }
873 } 906 }
874 break; 907 break;
@@ -877,7 +910,8 @@ static ssize_t cpu_configure_store(struct device *dev,
877 rc = sclp_cpu_configure(__cpu_logical_map[cpu]); 910 rc = sclp_cpu_configure(__cpu_logical_map[cpu]);
878 if (!rc) { 911 if (!rc) {
879 smp_cpu_state[cpu] = CPU_STATE_CONFIGURED; 912 smp_cpu_state[cpu] = CPU_STATE_CONFIGURED;
880 smp_cpu_polarization[cpu] = POLARIZATION_UNKNWN; 913 cpu_set_polarization(cpu, POLARIZATION_UNKNOWN);
914 topology_expect_change();
881 } 915 }
882 } 916 }
883 break; 917 break;
@@ -892,35 +926,6 @@ out:
892static DEVICE_ATTR(configure, 0644, cpu_configure_show, cpu_configure_store); 926static DEVICE_ATTR(configure, 0644, cpu_configure_show, cpu_configure_store);
893#endif /* CONFIG_HOTPLUG_CPU */ 927#endif /* CONFIG_HOTPLUG_CPU */
894 928
895static ssize_t cpu_polarization_show(struct device *dev,
896 struct device_attribute *attr, char *buf)
897{
898 int cpu = dev->id;
899 ssize_t count;
900
901 mutex_lock(&smp_cpu_state_mutex);
902 switch (smp_cpu_polarization[cpu]) {
903 case POLARIZATION_HRZ:
904 count = sprintf(buf, "horizontal\n");
905 break;
906 case POLARIZATION_VL:
907 count = sprintf(buf, "vertical:low\n");
908 break;
909 case POLARIZATION_VM:
910 count = sprintf(buf, "vertical:medium\n");
911 break;
912 case POLARIZATION_VH:
913 count = sprintf(buf, "vertical:high\n");
914 break;
915 default:
916 count = sprintf(buf, "unknown\n");
917 break;
918 }
919 mutex_unlock(&smp_cpu_state_mutex);
920 return count;
921}
922static DEVICE_ATTR(polarization, 0444, cpu_polarization_show, NULL);
923
924static ssize_t show_cpu_address(struct device *dev, 929static ssize_t show_cpu_address(struct device *dev,
925 struct device_attribute *attr, char *buf) 930 struct device_attribute *attr, char *buf)
926{ 931{
@@ -928,13 +933,11 @@ static ssize_t show_cpu_address(struct device *dev,
928} 933}
929static DEVICE_ATTR(address, 0444, show_cpu_address, NULL); 934static DEVICE_ATTR(address, 0444, show_cpu_address, NULL);
930 935
931
932static struct attribute *cpu_common_attrs[] = { 936static struct attribute *cpu_common_attrs[] = {
933#ifdef CONFIG_HOTPLUG_CPU 937#ifdef CONFIG_HOTPLUG_CPU
934 &dev_attr_configure.attr, 938 &dev_attr_configure.attr,
935#endif 939#endif
936 &dev_attr_address.attr, 940 &dev_attr_address.attr,
937 &dev_attr_polarization.attr,
938 NULL, 941 NULL,
939}; 942};
940 943
@@ -1055,11 +1058,20 @@ static int __devinit smp_add_present_cpu(int cpu)
1055 rc = sysfs_create_group(&s->kobj, &cpu_common_attr_group); 1058 rc = sysfs_create_group(&s->kobj, &cpu_common_attr_group);
1056 if (rc) 1059 if (rc)
1057 goto out_cpu; 1060 goto out_cpu;
1058 if (!cpu_online(cpu)) 1061 if (cpu_online(cpu)) {
1059 goto out; 1062 rc = sysfs_create_group(&s->kobj, &cpu_online_attr_group);
1060 rc = sysfs_create_group(&s->kobj, &cpu_online_attr_group); 1063 if (rc)
1061 if (!rc) 1064 goto out_online;
1062 return 0; 1065 }
1066 rc = topology_cpu_init(c);
1067 if (rc)
1068 goto out_topology;
1069 return 0;
1070
1071out_topology:
1072 if (cpu_online(cpu))
1073 sysfs_remove_group(&s->kobj, &cpu_online_attr_group);
1074out_online:
1063 sysfs_remove_group(&s->kobj, &cpu_common_attr_group); 1075 sysfs_remove_group(&s->kobj, &cpu_common_attr_group);
1064out_cpu: 1076out_cpu:
1065#ifdef CONFIG_HOTPLUG_CPU 1077#ifdef CONFIG_HOTPLUG_CPU
@@ -1111,61 +1123,16 @@ static ssize_t __ref rescan_store(struct device *dev,
1111static DEVICE_ATTR(rescan, 0200, NULL, rescan_store); 1123static DEVICE_ATTR(rescan, 0200, NULL, rescan_store);
1112#endif /* CONFIG_HOTPLUG_CPU */ 1124#endif /* CONFIG_HOTPLUG_CPU */
1113 1125
1114static ssize_t dispatching_show(struct device *dev, 1126static int __init s390_smp_init(void)
1115 struct device_attribute *attr,
1116 char *buf)
1117{
1118 ssize_t count;
1119
1120 mutex_lock(&smp_cpu_state_mutex);
1121 count = sprintf(buf, "%d\n", cpu_management);
1122 mutex_unlock(&smp_cpu_state_mutex);
1123 return count;
1124}
1125
1126static ssize_t dispatching_store(struct device *dev,
1127 struct device_attribute *attr,
1128 const char *buf,
1129 size_t count)
1130{
1131 int val, rc;
1132 char delim;
1133
1134 if (sscanf(buf, "%d %c", &val, &delim) != 1)
1135 return -EINVAL;
1136 if (val != 0 && val != 1)
1137 return -EINVAL;
1138 rc = 0;
1139 get_online_cpus();
1140 mutex_lock(&smp_cpu_state_mutex);
1141 if (cpu_management == val)
1142 goto out;
1143 rc = topology_set_cpu_management(val);
1144 if (!rc)
1145 cpu_management = val;
1146out:
1147 mutex_unlock(&smp_cpu_state_mutex);
1148 put_online_cpus();
1149 return rc ? rc : count;
1150}
1151static DEVICE_ATTR(dispatching, 0644, dispatching_show,
1152 dispatching_store);
1153
1154static int __init topology_init(void)
1155{ 1127{
1156 int cpu; 1128 int cpu, rc;
1157 int rc;
1158 1129
1159 register_cpu_notifier(&smp_cpu_nb); 1130 register_cpu_notifier(&smp_cpu_nb);
1160
1161#ifdef CONFIG_HOTPLUG_CPU 1131#ifdef CONFIG_HOTPLUG_CPU
1162 rc = device_create_file(cpu_subsys.dev_root, &dev_attr_rescan); 1132 rc = device_create_file(cpu_subsys.dev_root, &dev_attr_rescan);
1163 if (rc) 1133 if (rc)
1164 return rc; 1134 return rc;
1165#endif 1135#endif
1166 rc = device_create_file(cpu_subsys.dev_root, &dev_attr_dispatching);
1167 if (rc)
1168 return rc;
1169 for_each_present_cpu(cpu) { 1136 for_each_present_cpu(cpu) {
1170 rc = smp_add_present_cpu(cpu); 1137 rc = smp_add_present_cpu(cpu);
1171 if (rc) 1138 if (rc)
@@ -1173,4 +1140,4 @@ static int __init topology_init(void)
1173 } 1140 }
1174 return 0; 1141 return 0;
1175} 1142}
1176subsys_initcall(topology_init); 1143subsys_initcall(s390_smp_init);
diff --git a/arch/s390/kernel/sys_s390.c b/arch/s390/kernel/sys_s390.c
index 476081440df9..78ea1948ff51 100644
--- a/arch/s390/kernel/sys_s390.c
+++ b/arch/s390/kernel/sys_s390.c
@@ -60,74 +60,22 @@ out:
60} 60}
61 61
62/* 62/*
63 * sys_ipc() is the de-multiplexer for the SysV IPC calls.. 63 * sys_ipc() is the de-multiplexer for the SysV IPC calls.
64 *
65 * This is really horribly ugly.
66 */ 64 */
67SYSCALL_DEFINE5(s390_ipc, uint, call, int, first, unsigned long, second, 65SYSCALL_DEFINE5(s390_ipc, uint, call, int, first, unsigned long, second,
68 unsigned long, third, void __user *, ptr) 66 unsigned long, third, void __user *, ptr)
69{ 67{
70 struct ipc_kludge tmp; 68 if (call >> 16)
71 int ret; 69 return -EINVAL;
72 70 /* The s390 sys_ipc variant has only five parameters instead of six
73 switch (call) { 71 * like the generic variant. The only difference is the handling of
74 case SEMOP: 72 * the SEMTIMEDOP subcall where on s390 the third parameter is used
75 return sys_semtimedop(first, (struct sembuf __user *)ptr, 73 * as a pointer to a struct timespec where the generic variant uses
76 (unsigned)second, NULL); 74 * the fifth parameter.
77 case SEMTIMEDOP: 75 * Therefore we can call the generic variant by simply passing the
78 return sys_semtimedop(first, (struct sembuf __user *)ptr, 76 * third parameter also as fifth parameter.
79 (unsigned)second, 77 */
80 (const struct timespec __user *) third); 78 return sys_ipc(call, first, second, third, ptr, third);
81 case SEMGET:
82 return sys_semget(first, (int)second, third);
83 case SEMCTL: {
84 union semun fourth;
85 if (!ptr)
86 return -EINVAL;
87 if (get_user(fourth.__pad, (void __user * __user *) ptr))
88 return -EFAULT;
89 return sys_semctl(first, (int)second, third, fourth);
90 }
91 case MSGSND:
92 return sys_msgsnd (first, (struct msgbuf __user *) ptr,
93 (size_t)second, third);
94 break;
95 case MSGRCV:
96 if (!ptr)
97 return -EINVAL;
98 if (copy_from_user (&tmp, (struct ipc_kludge __user *) ptr,
99 sizeof (struct ipc_kludge)))
100 return -EFAULT;
101 return sys_msgrcv (first, tmp.msgp,
102 (size_t)second, tmp.msgtyp, third);
103 case MSGGET:
104 return sys_msgget((key_t)first, (int)second);
105 case MSGCTL:
106 return sys_msgctl(first, (int)second,
107 (struct msqid_ds __user *)ptr);
108
109 case SHMAT: {
110 ulong raddr;
111 ret = do_shmat(first, (char __user *)ptr,
112 (int)second, &raddr);
113 if (ret)
114 return ret;
115 return put_user (raddr, (ulong __user *) third);
116 break;
117 }
118 case SHMDT:
119 return sys_shmdt ((char __user *)ptr);
120 case SHMGET:
121 return sys_shmget(first, (size_t)second, third);
122 case SHMCTL:
123 return sys_shmctl(first, (int)second,
124 (struct shmid_ds __user *) ptr);
125 default:
126 return -ENOSYS;
127
128 }
129
130 return -EINVAL;
131} 79}
132 80
133#ifdef CONFIG_64BIT 81#ifdef CONFIG_64BIT
diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c
index 6e0e29b29a7b..7370a41948ca 100644
--- a/arch/s390/kernel/topology.c
+++ b/arch/s390/kernel/topology.c
@@ -1,22 +1,22 @@
1/* 1/*
2 * Copyright IBM Corp. 2007 2 * Copyright IBM Corp. 2007,2011
3 * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com> 3 * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>
4 */ 4 */
5 5
6#define KMSG_COMPONENT "cpu" 6#define KMSG_COMPONENT "cpu"
7#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 7#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
8 8
9#include <linux/kernel.h> 9#include <linux/workqueue.h>
10#include <linux/mm.h>
11#include <linux/init.h>
12#include <linux/device.h>
13#include <linux/bootmem.h> 10#include <linux/bootmem.h>
11#include <linux/cpuset.h>
12#include <linux/device.h>
13#include <linux/kernel.h>
14#include <linux/sched.h> 14#include <linux/sched.h>
15#include <linux/workqueue.h> 15#include <linux/init.h>
16#include <linux/delay.h>
16#include <linux/cpu.h> 17#include <linux/cpu.h>
17#include <linux/smp.h> 18#include <linux/smp.h>
18#include <linux/cpuset.h> 19#include <linux/mm.h>
19#include <asm/delay.h>
20 20
21#define PTF_HORIZONTAL (0UL) 21#define PTF_HORIZONTAL (0UL)
22#define PTF_VERTICAL (1UL) 22#define PTF_VERTICAL (1UL)
@@ -31,7 +31,6 @@ struct mask_info {
31static int topology_enabled = 1; 31static int topology_enabled = 1;
32static void topology_work_fn(struct work_struct *work); 32static void topology_work_fn(struct work_struct *work);
33static struct sysinfo_15_1_x *tl_info; 33static struct sysinfo_15_1_x *tl_info;
34static struct timer_list topology_timer;
35static void set_topology_timer(void); 34static void set_topology_timer(void);
36static DECLARE_WORK(topology_work, topology_work_fn); 35static DECLARE_WORK(topology_work, topology_work_fn);
37/* topology_lock protects the core linked list */ 36/* topology_lock protects the core linked list */
@@ -41,11 +40,12 @@ static struct mask_info core_info;
41cpumask_t cpu_core_map[NR_CPUS]; 40cpumask_t cpu_core_map[NR_CPUS];
42unsigned char cpu_core_id[NR_CPUS]; 41unsigned char cpu_core_id[NR_CPUS];
43 42
44#ifdef CONFIG_SCHED_BOOK
45static struct mask_info book_info; 43static struct mask_info book_info;
46cpumask_t cpu_book_map[NR_CPUS]; 44cpumask_t cpu_book_map[NR_CPUS];
47unsigned char cpu_book_id[NR_CPUS]; 45unsigned char cpu_book_id[NR_CPUS];
48#endif 46
47/* smp_cpu_state_mutex must be held when accessing this array */
48int cpu_polarization[NR_CPUS];
49 49
50static cpumask_t cpu_group_map(struct mask_info *info, unsigned int cpu) 50static cpumask_t cpu_group_map(struct mask_info *info, unsigned int cpu)
51{ 51{
@@ -71,7 +71,7 @@ static cpumask_t cpu_group_map(struct mask_info *info, unsigned int cpu)
71static struct mask_info *add_cpus_to_mask(struct topology_cpu *tl_cpu, 71static struct mask_info *add_cpus_to_mask(struct topology_cpu *tl_cpu,
72 struct mask_info *book, 72 struct mask_info *book,
73 struct mask_info *core, 73 struct mask_info *core,
74 int z10) 74 int one_core_per_cpu)
75{ 75{
76 unsigned int cpu; 76 unsigned int cpu;
77 77
@@ -85,18 +85,16 @@ static struct mask_info *add_cpus_to_mask(struct topology_cpu *tl_cpu,
85 for_each_present_cpu(lcpu) { 85 for_each_present_cpu(lcpu) {
86 if (cpu_logical_map(lcpu) != rcpu) 86 if (cpu_logical_map(lcpu) != rcpu)
87 continue; 87 continue;
88#ifdef CONFIG_SCHED_BOOK
89 cpumask_set_cpu(lcpu, &book->mask); 88 cpumask_set_cpu(lcpu, &book->mask);
90 cpu_book_id[lcpu] = book->id; 89 cpu_book_id[lcpu] = book->id;
91#endif
92 cpumask_set_cpu(lcpu, &core->mask); 90 cpumask_set_cpu(lcpu, &core->mask);
93 if (z10) { 91 if (one_core_per_cpu) {
94 cpu_core_id[lcpu] = rcpu; 92 cpu_core_id[lcpu] = rcpu;
95 core = core->next; 93 core = core->next;
96 } else { 94 } else {
97 cpu_core_id[lcpu] = core->id; 95 cpu_core_id[lcpu] = core->id;
98 } 96 }
99 smp_cpu_polarization[lcpu] = tl_cpu->pp; 97 cpu_set_polarization(lcpu, tl_cpu->pp);
100 } 98 }
101 } 99 }
102 return core; 100 return core;
@@ -111,13 +109,11 @@ static void clear_masks(void)
111 cpumask_clear(&info->mask); 109 cpumask_clear(&info->mask);
112 info = info->next; 110 info = info->next;
113 } 111 }
114#ifdef CONFIG_SCHED_BOOK
115 info = &book_info; 112 info = &book_info;
116 while (info) { 113 while (info) {
117 cpumask_clear(&info->mask); 114 cpumask_clear(&info->mask);
118 info = info->next; 115 info = info->next;
119 } 116 }
120#endif
121} 117}
122 118
123static union topology_entry *next_tle(union topology_entry *tle) 119static union topology_entry *next_tle(union topology_entry *tle)
@@ -127,66 +123,75 @@ static union topology_entry *next_tle(union topology_entry *tle)
127 return (union topology_entry *)((struct topology_container *)tle + 1); 123 return (union topology_entry *)((struct topology_container *)tle + 1);
128} 124}
129 125
130static void tl_to_cores(struct sysinfo_15_1_x *info) 126static void __tl_to_cores_generic(struct sysinfo_15_1_x *info)
131{ 127{
132#ifdef CONFIG_SCHED_BOOK
133 struct mask_info *book = &book_info;
134 struct cpuid cpu_id;
135#else
136 struct mask_info *book = NULL;
137#endif
138 struct mask_info *core = &core_info; 128 struct mask_info *core = &core_info;
129 struct mask_info *book = &book_info;
139 union topology_entry *tle, *end; 130 union topology_entry *tle, *end;
140 int z10 = 0;
141 131
142#ifdef CONFIG_SCHED_BOOK
143 get_cpu_id(&cpu_id);
144 z10 = cpu_id.machine == 0x2097 || cpu_id.machine == 0x2098;
145#endif
146 spin_lock_irq(&topology_lock);
147 clear_masks();
148 tle = info->tle; 132 tle = info->tle;
149 end = (union topology_entry *)((unsigned long)info + info->length); 133 end = (union topology_entry *)((unsigned long)info + info->length);
150 while (tle < end) { 134 while (tle < end) {
151#ifdef CONFIG_SCHED_BOOK
152 if (z10) {
153 switch (tle->nl) {
154 case 1:
155 book = book->next;
156 book->id = tle->container.id;
157 break;
158 case 0:
159 core = add_cpus_to_mask(&tle->cpu, book, core, z10);
160 break;
161 default:
162 clear_masks();
163 goto out;
164 }
165 tle = next_tle(tle);
166 continue;
167 }
168#endif
169 switch (tle->nl) { 135 switch (tle->nl) {
170#ifdef CONFIG_SCHED_BOOK
171 case 2: 136 case 2:
172 book = book->next; 137 book = book->next;
173 book->id = tle->container.id; 138 book->id = tle->container.id;
174 break; 139 break;
175#endif
176 case 1: 140 case 1:
177 core = core->next; 141 core = core->next;
178 core->id = tle->container.id; 142 core->id = tle->container.id;
179 break; 143 break;
180 case 0: 144 case 0:
181 add_cpus_to_mask(&tle->cpu, book, core, z10); 145 add_cpus_to_mask(&tle->cpu, book, core, 0);
182 break; 146 break;
183 default: 147 default:
184 clear_masks(); 148 clear_masks();
185 goto out; 149 return;
186 } 150 }
187 tle = next_tle(tle); 151 tle = next_tle(tle);
188 } 152 }
189out: 153}
154
155static void __tl_to_cores_z10(struct sysinfo_15_1_x *info)
156{
157 struct mask_info *core = &core_info;
158 struct mask_info *book = &book_info;
159 union topology_entry *tle, *end;
160
161 tle = info->tle;
162 end = (union topology_entry *)((unsigned long)info + info->length);
163 while (tle < end) {
164 switch (tle->nl) {
165 case 1:
166 book = book->next;
167 book->id = tle->container.id;
168 break;
169 case 0:
170 core = add_cpus_to_mask(&tle->cpu, book, core, 1);
171 break;
172 default:
173 clear_masks();
174 return;
175 }
176 tle = next_tle(tle);
177 }
178}
179
180static void tl_to_cores(struct sysinfo_15_1_x *info)
181{
182 struct cpuid cpu_id;
183
184 get_cpu_id(&cpu_id);
185 spin_lock_irq(&topology_lock);
186 clear_masks();
187 switch (cpu_id.machine) {
188 case 0x2097:
189 case 0x2098:
190 __tl_to_cores_z10(info);
191 break;
192 default:
193 __tl_to_cores_generic(info);
194 }
190 spin_unlock_irq(&topology_lock); 195 spin_unlock_irq(&topology_lock);
191} 196}
192 197
@@ -196,7 +201,7 @@ static void topology_update_polarization_simple(void)
196 201
197 mutex_lock(&smp_cpu_state_mutex); 202 mutex_lock(&smp_cpu_state_mutex);
198 for_each_possible_cpu(cpu) 203 for_each_possible_cpu(cpu)
199 smp_cpu_polarization[cpu] = POLARIZATION_HRZ; 204 cpu_set_polarization(cpu, POLARIZATION_HRZ);
200 mutex_unlock(&smp_cpu_state_mutex); 205 mutex_unlock(&smp_cpu_state_mutex);
201} 206}
202 207
@@ -215,8 +220,7 @@ static int ptf(unsigned long fc)
215 220
216int topology_set_cpu_management(int fc) 221int topology_set_cpu_management(int fc)
217{ 222{
218 int cpu; 223 int cpu, rc;
219 int rc;
220 224
221 if (!MACHINE_HAS_TOPOLOGY) 225 if (!MACHINE_HAS_TOPOLOGY)
222 return -EOPNOTSUPP; 226 return -EOPNOTSUPP;
@@ -227,7 +231,7 @@ int topology_set_cpu_management(int fc)
227 if (rc) 231 if (rc)
228 return -EBUSY; 232 return -EBUSY;
229 for_each_possible_cpu(cpu) 233 for_each_possible_cpu(cpu)
230 smp_cpu_polarization[cpu] = POLARIZATION_UNKNWN; 234 cpu_set_polarization(cpu, POLARIZATION_UNKNOWN);
231 return rc; 235 return rc;
232} 236}
233 237
@@ -239,22 +243,18 @@ static void update_cpu_core_map(void)
239 spin_lock_irqsave(&topology_lock, flags); 243 spin_lock_irqsave(&topology_lock, flags);
240 for_each_possible_cpu(cpu) { 244 for_each_possible_cpu(cpu) {
241 cpu_core_map[cpu] = cpu_group_map(&core_info, cpu); 245 cpu_core_map[cpu] = cpu_group_map(&core_info, cpu);
242#ifdef CONFIG_SCHED_BOOK
243 cpu_book_map[cpu] = cpu_group_map(&book_info, cpu); 246 cpu_book_map[cpu] = cpu_group_map(&book_info, cpu);
244#endif
245 } 247 }
246 spin_unlock_irqrestore(&topology_lock, flags); 248 spin_unlock_irqrestore(&topology_lock, flags);
247} 249}
248 250
249void store_topology(struct sysinfo_15_1_x *info) 251void store_topology(struct sysinfo_15_1_x *info)
250{ 252{
251#ifdef CONFIG_SCHED_BOOK
252 int rc; 253 int rc;
253 254
254 rc = stsi(info, 15, 1, 3); 255 rc = stsi(info, 15, 1, 3);
255 if (rc != -ENOSYS) 256 if (rc != -ENOSYS)
256 return; 257 return;
257#endif
258 stsi(info, 15, 1, 2); 258 stsi(info, 15, 1, 2);
259} 259}
260 260
@@ -296,12 +296,30 @@ static void topology_timer_fn(unsigned long ignored)
296 set_topology_timer(); 296 set_topology_timer();
297} 297}
298 298
299static struct timer_list topology_timer =
300 TIMER_DEFERRED_INITIALIZER(topology_timer_fn, 0, 0);
301
302static atomic_t topology_poll = ATOMIC_INIT(0);
303
299static void set_topology_timer(void) 304static void set_topology_timer(void)
300{ 305{
301 topology_timer.function = topology_timer_fn; 306 if (atomic_add_unless(&topology_poll, -1, 0))
302 topology_timer.data = 0; 307 mod_timer(&topology_timer, jiffies + HZ / 10);
303 topology_timer.expires = jiffies + 60 * HZ; 308 else
304 add_timer(&topology_timer); 309 mod_timer(&topology_timer, jiffies + HZ * 60);
310}
311
312void topology_expect_change(void)
313{
314 if (!MACHINE_HAS_TOPOLOGY)
315 return;
316 /* This is racy, but it doesn't matter since it is just a heuristic.
317 * Worst case is that we poll in a higher frequency for a bit longer.
318 */
319 if (atomic_read(&topology_poll) > 60)
320 return;
321 atomic_add(60, &topology_poll);
322 set_topology_timer();
305} 323}
306 324
307static int __init early_parse_topology(char *p) 325static int __init early_parse_topology(char *p)
@@ -313,23 +331,6 @@ static int __init early_parse_topology(char *p)
313} 331}
314early_param("topology", early_parse_topology); 332early_param("topology", early_parse_topology);
315 333
316static int __init init_topology_update(void)
317{
318 int rc;
319
320 rc = 0;
321 if (!MACHINE_HAS_TOPOLOGY) {
322 topology_update_polarization_simple();
323 goto out;
324 }
325 init_timer_deferrable(&topology_timer);
326 set_topology_timer();
327out:
328 update_cpu_core_map();
329 return rc;
330}
331__initcall(init_topology_update);
332
333static void __init alloc_masks(struct sysinfo_15_1_x *info, 334static void __init alloc_masks(struct sysinfo_15_1_x *info,
334 struct mask_info *mask, int offset) 335 struct mask_info *mask, int offset)
335{ 336{
@@ -357,10 +358,108 @@ void __init s390_init_cpu_topology(void)
357 store_topology(info); 358 store_topology(info);
358 pr_info("The CPU configuration topology of the machine is:"); 359 pr_info("The CPU configuration topology of the machine is:");
359 for (i = 0; i < TOPOLOGY_NR_MAG; i++) 360 for (i = 0; i < TOPOLOGY_NR_MAG; i++)
360 printk(" %d", info->mag[i]); 361 printk(KERN_CONT " %d", info->mag[i]);
361 printk(" / %d\n", info->mnest); 362 printk(KERN_CONT " / %d\n", info->mnest);
362 alloc_masks(info, &core_info, 1); 363 alloc_masks(info, &core_info, 1);
363#ifdef CONFIG_SCHED_BOOK
364 alloc_masks(info, &book_info, 2); 364 alloc_masks(info, &book_info, 2);
365#endif
366} 365}
366
367static int cpu_management;
368
369static ssize_t dispatching_show(struct device *dev,
370 struct device_attribute *attr,
371 char *buf)
372{
373 ssize_t count;
374
375 mutex_lock(&smp_cpu_state_mutex);
376 count = sprintf(buf, "%d\n", cpu_management);
377 mutex_unlock(&smp_cpu_state_mutex);
378 return count;
379}
380
381static ssize_t dispatching_store(struct device *dev,
382 struct device_attribute *attr,
383 const char *buf,
384 size_t count)
385{
386 int val, rc;
387 char delim;
388
389 if (sscanf(buf, "%d %c", &val, &delim) != 1)
390 return -EINVAL;
391 if (val != 0 && val != 1)
392 return -EINVAL;
393 rc = 0;
394 get_online_cpus();
395 mutex_lock(&smp_cpu_state_mutex);
396 if (cpu_management == val)
397 goto out;
398 rc = topology_set_cpu_management(val);
399 if (rc)
400 goto out;
401 cpu_management = val;
402 topology_expect_change();
403out:
404 mutex_unlock(&smp_cpu_state_mutex);
405 put_online_cpus();
406 return rc ? rc : count;
407}
408static DEVICE_ATTR(dispatching, 0644, dispatching_show,
409 dispatching_store);
410
411static ssize_t cpu_polarization_show(struct device *dev,
412 struct device_attribute *attr, char *buf)
413{
414 int cpu = dev->id;
415 ssize_t count;
416
417 mutex_lock(&smp_cpu_state_mutex);
418 switch (cpu_read_polarization(cpu)) {
419 case POLARIZATION_HRZ:
420 count = sprintf(buf, "horizontal\n");
421 break;
422 case POLARIZATION_VL:
423 count = sprintf(buf, "vertical:low\n");
424 break;
425 case POLARIZATION_VM:
426 count = sprintf(buf, "vertical:medium\n");
427 break;
428 case POLARIZATION_VH:
429 count = sprintf(buf, "vertical:high\n");
430 break;
431 default:
432 count = sprintf(buf, "unknown\n");
433 break;
434 }
435 mutex_unlock(&smp_cpu_state_mutex);
436 return count;
437}
438static DEVICE_ATTR(polarization, 0444, cpu_polarization_show, NULL);
439
440static struct attribute *topology_cpu_attrs[] = {
441 &dev_attr_polarization.attr,
442 NULL,
443};
444
445static struct attribute_group topology_cpu_attr_group = {
446 .attrs = topology_cpu_attrs,
447};
448
449int topology_cpu_init(struct cpu *cpu)
450{
451 return sysfs_create_group(&cpu->dev.kobj, &topology_cpu_attr_group);
452}
453
454static int __init topology_init(void)
455{
456 if (!MACHINE_HAS_TOPOLOGY) {
457 topology_update_polarization_simple();
458 goto out;
459 }
460 set_topology_timer();
461out:
462 update_cpu_core_map();
463 return device_create_file(cpu_subsys.dev_root, &dev_attr_dispatching);
464}
465device_initcall(topology_init);
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index a9807dd86276..5ce3750b181f 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -43,9 +43,9 @@
43#include <asm/debug.h> 43#include <asm/debug.h>
44#include "entry.h" 44#include "entry.h"
45 45
46void (*pgm_check_table[128])(struct pt_regs *, long, unsigned long); 46void (*pgm_check_table[128])(struct pt_regs *regs);
47 47
48int show_unhandled_signals; 48int show_unhandled_signals = 1;
49 49
50#define stack_pointer ({ void **sp; asm("la %0,0(15)" : "=&d" (sp)); sp; }) 50#define stack_pointer ({ void **sp; asm("la %0,0(15)" : "=&d" (sp)); sp; })
51 51
@@ -234,7 +234,7 @@ void show_regs(struct pt_regs *regs)
234 234
235static DEFINE_SPINLOCK(die_lock); 235static DEFINE_SPINLOCK(die_lock);
236 236
237void die(const char * str, struct pt_regs * regs, long err) 237void die(struct pt_regs *regs, const char *str)
238{ 238{
239 static int die_counter; 239 static int die_counter;
240 240
@@ -243,7 +243,7 @@ void die(const char * str, struct pt_regs * regs, long err)
243 console_verbose(); 243 console_verbose();
244 spin_lock_irq(&die_lock); 244 spin_lock_irq(&die_lock);
245 bust_spinlocks(1); 245 bust_spinlocks(1);
246 printk("%s: %04lx [#%d] ", str, err & 0xffff, ++die_counter); 246 printk("%s: %04x [#%d] ", str, regs->int_code & 0xffff, ++die_counter);
247#ifdef CONFIG_PREEMPT 247#ifdef CONFIG_PREEMPT
248 printk("PREEMPT "); 248 printk("PREEMPT ");
249#endif 249#endif
@@ -254,7 +254,7 @@ void die(const char * str, struct pt_regs * regs, long err)
254 printk("DEBUG_PAGEALLOC"); 254 printk("DEBUG_PAGEALLOC");
255#endif 255#endif
256 printk("\n"); 256 printk("\n");
257 notify_die(DIE_OOPS, str, regs, err, current->thread.trap_no, SIGSEGV); 257 notify_die(DIE_OOPS, str, regs, 0, regs->int_code & 0xffff, SIGSEGV);
258 show_regs(regs); 258 show_regs(regs);
259 bust_spinlocks(0); 259 bust_spinlocks(0);
260 add_taint(TAINT_DIE); 260 add_taint(TAINT_DIE);
@@ -267,8 +267,7 @@ void die(const char * str, struct pt_regs * regs, long err)
267 do_exit(SIGSEGV); 267 do_exit(SIGSEGV);
268} 268}
269 269
270static void inline report_user_fault(struct pt_regs *regs, long int_code, 270static inline void report_user_fault(struct pt_regs *regs, int signr)
271 int signr)
272{ 271{
273 if ((task_pid_nr(current) > 1) && !show_unhandled_signals) 272 if ((task_pid_nr(current) > 1) && !show_unhandled_signals)
274 return; 273 return;
@@ -276,7 +275,7 @@ static void inline report_user_fault(struct pt_regs *regs, long int_code,
276 return; 275 return;
277 if (!printk_ratelimit()) 276 if (!printk_ratelimit())
278 return; 277 return;
279 printk("User process fault: interruption code 0x%lX ", int_code); 278 printk("User process fault: interruption code 0x%X ", regs->int_code);
280 print_vma_addr("in ", regs->psw.addr & PSW_ADDR_INSN); 279 print_vma_addr("in ", regs->psw.addr & PSW_ADDR_INSN);
281 printk("\n"); 280 printk("\n");
282 show_regs(regs); 281 show_regs(regs);
@@ -287,19 +286,28 @@ int is_valid_bugaddr(unsigned long addr)
287 return 1; 286 return 1;
288} 287}
289 288
290static inline void __kprobes do_trap(long pgm_int_code, int signr, char *str, 289static inline void __user *get_psw_address(struct pt_regs *regs)
291 struct pt_regs *regs, siginfo_t *info)
292{ 290{
293 if (notify_die(DIE_TRAP, str, regs, pgm_int_code, 291 return (void __user *)
294 pgm_int_code, signr) == NOTIFY_STOP) 292 ((regs->psw.addr - (regs->int_code >> 16)) & PSW_ADDR_INSN);
293}
294
295static void __kprobes do_trap(struct pt_regs *regs,
296 int si_signo, int si_code, char *str)
297{
298 siginfo_t info;
299
300 if (notify_die(DIE_TRAP, str, regs, 0,
301 regs->int_code, si_signo) == NOTIFY_STOP)
295 return; 302 return;
296 303
297 if (regs->psw.mask & PSW_MASK_PSTATE) { 304 if (regs->psw.mask & PSW_MASK_PSTATE) {
298 struct task_struct *tsk = current; 305 info.si_signo = si_signo;
299 306 info.si_errno = 0;
300 tsk->thread.trap_no = pgm_int_code & 0xffff; 307 info.si_code = si_code;
301 force_sig_info(signr, info, tsk); 308 info.si_addr = get_psw_address(regs);
302 report_user_fault(regs, pgm_int_code, signr); 309 force_sig_info(si_signo, &info, current);
310 report_user_fault(regs, si_signo);
303 } else { 311 } else {
304 const struct exception_table_entry *fixup; 312 const struct exception_table_entry *fixup;
305 fixup = search_exception_tables(regs->psw.addr & PSW_ADDR_INSN); 313 fixup = search_exception_tables(regs->psw.addr & PSW_ADDR_INSN);
@@ -311,18 +319,11 @@ static inline void __kprobes do_trap(long pgm_int_code, int signr, char *str,
311 btt = report_bug(regs->psw.addr & PSW_ADDR_INSN, regs); 319 btt = report_bug(regs->psw.addr & PSW_ADDR_INSN, regs);
312 if (btt == BUG_TRAP_TYPE_WARN) 320 if (btt == BUG_TRAP_TYPE_WARN)
313 return; 321 return;
314 die(str, regs, pgm_int_code); 322 die(regs, str);
315 } 323 }
316 } 324 }
317} 325}
318 326
319static inline void __user *get_psw_address(struct pt_regs *regs,
320 long pgm_int_code)
321{
322 return (void __user *)
323 ((regs->psw.addr - (pgm_int_code >> 16)) & PSW_ADDR_INSN);
324}
325
326void __kprobes do_per_trap(struct pt_regs *regs) 327void __kprobes do_per_trap(struct pt_regs *regs)
327{ 328{
328 siginfo_t info; 329 siginfo_t info;
@@ -339,26 +340,19 @@ void __kprobes do_per_trap(struct pt_regs *regs)
339 force_sig_info(SIGTRAP, &info, current); 340 force_sig_info(SIGTRAP, &info, current);
340} 341}
341 342
342static void default_trap_handler(struct pt_regs *regs, long pgm_int_code, 343static void default_trap_handler(struct pt_regs *regs)
343 unsigned long trans_exc_code)
344{ 344{
345 if (regs->psw.mask & PSW_MASK_PSTATE) { 345 if (regs->psw.mask & PSW_MASK_PSTATE) {
346 report_user_fault(regs, pgm_int_code, SIGSEGV); 346 report_user_fault(regs, SIGSEGV);
347 do_exit(SIGSEGV); 347 do_exit(SIGSEGV);
348 } else 348 } else
349 die("Unknown program exception", regs, pgm_int_code); 349 die(regs, "Unknown program exception");
350} 350}
351 351
352#define DO_ERROR_INFO(name, signr, sicode, str) \ 352#define DO_ERROR_INFO(name, signr, sicode, str) \
353static void name(struct pt_regs *regs, long pgm_int_code, \ 353static void name(struct pt_regs *regs) \
354 unsigned long trans_exc_code) \
355{ \ 354{ \
356 siginfo_t info; \ 355 do_trap(regs, signr, sicode, str); \
357 info.si_signo = signr; \
358 info.si_errno = 0; \
359 info.si_code = sicode; \
360 info.si_addr = get_psw_address(regs, pgm_int_code); \
361 do_trap(pgm_int_code, signr, str, regs, &info); \
362} 356}
363 357
364DO_ERROR_INFO(addressing_exception, SIGILL, ILL_ILLADR, 358DO_ERROR_INFO(addressing_exception, SIGILL, ILL_ILLADR,
@@ -388,42 +382,34 @@ DO_ERROR_INFO(special_op_exception, SIGILL, ILL_ILLOPN,
388DO_ERROR_INFO(translation_exception, SIGILL, ILL_ILLOPN, 382DO_ERROR_INFO(translation_exception, SIGILL, ILL_ILLOPN,
389 "translation exception") 383 "translation exception")
390 384
391static inline void do_fp_trap(struct pt_regs *regs, void __user *location, 385static inline void do_fp_trap(struct pt_regs *regs, int fpc)
392 int fpc, long pgm_int_code)
393{ 386{
394 siginfo_t si; 387 int si_code = 0;
395
396 si.si_signo = SIGFPE;
397 si.si_errno = 0;
398 si.si_addr = location;
399 si.si_code = 0;
400 /* FPC[2] is Data Exception Code */ 388 /* FPC[2] is Data Exception Code */
401 if ((fpc & 0x00000300) == 0) { 389 if ((fpc & 0x00000300) == 0) {
402 /* bits 6 and 7 of DXC are 0 iff IEEE exception */ 390 /* bits 6 and 7 of DXC are 0 iff IEEE exception */
403 if (fpc & 0x8000) /* invalid fp operation */ 391 if (fpc & 0x8000) /* invalid fp operation */
404 si.si_code = FPE_FLTINV; 392 si_code = FPE_FLTINV;
405 else if (fpc & 0x4000) /* div by 0 */ 393 else if (fpc & 0x4000) /* div by 0 */
406 si.si_code = FPE_FLTDIV; 394 si_code = FPE_FLTDIV;
407 else if (fpc & 0x2000) /* overflow */ 395 else if (fpc & 0x2000) /* overflow */
408 si.si_code = FPE_FLTOVF; 396 si_code = FPE_FLTOVF;
409 else if (fpc & 0x1000) /* underflow */ 397 else if (fpc & 0x1000) /* underflow */
410 si.si_code = FPE_FLTUND; 398 si_code = FPE_FLTUND;
411 else if (fpc & 0x0800) /* inexact */ 399 else if (fpc & 0x0800) /* inexact */
412 si.si_code = FPE_FLTRES; 400 si_code = FPE_FLTRES;
413 } 401 }
414 do_trap(pgm_int_code, SIGFPE, 402 do_trap(regs, SIGFPE, si_code, "floating point exception");
415 "floating point exception", regs, &si);
416} 403}
417 404
418static void __kprobes illegal_op(struct pt_regs *regs, long pgm_int_code, 405static void __kprobes illegal_op(struct pt_regs *regs)
419 unsigned long trans_exc_code)
420{ 406{
421 siginfo_t info; 407 siginfo_t info;
422 __u8 opcode[6]; 408 __u8 opcode[6];
423 __u16 __user *location; 409 __u16 __user *location;
424 int signal = 0; 410 int signal = 0;
425 411
426 location = get_psw_address(regs, pgm_int_code); 412 location = get_psw_address(regs);
427 413
428 if (regs->psw.mask & PSW_MASK_PSTATE) { 414 if (regs->psw.mask & PSW_MASK_PSTATE) {
429 if (get_user(*((__u16 *) opcode), (__u16 __user *) location)) 415 if (get_user(*((__u16 *) opcode), (__u16 __user *) location))
@@ -467,44 +453,31 @@ static void __kprobes illegal_op(struct pt_regs *regs, long pgm_int_code,
467 * If we get an illegal op in kernel mode, send it through the 453 * If we get an illegal op in kernel mode, send it through the
468 * kprobes notifier. If kprobes doesn't pick it up, SIGILL 454 * kprobes notifier. If kprobes doesn't pick it up, SIGILL
469 */ 455 */
470 if (notify_die(DIE_BPT, "bpt", regs, pgm_int_code, 456 if (notify_die(DIE_BPT, "bpt", regs, 0,
471 3, SIGTRAP) != NOTIFY_STOP) 457 3, SIGTRAP) != NOTIFY_STOP)
472 signal = SIGILL; 458 signal = SIGILL;
473 } 459 }
474 460
475#ifdef CONFIG_MATHEMU 461#ifdef CONFIG_MATHEMU
476 if (signal == SIGFPE) 462 if (signal == SIGFPE)
477 do_fp_trap(regs, location, 463 do_fp_trap(regs, current->thread.fp_regs.fpc);
478 current->thread.fp_regs.fpc, pgm_int_code); 464 else if (signal == SIGSEGV)
479 else if (signal == SIGSEGV) { 465 do_trap(regs, signal, SEGV_MAPERR, "user address fault");
480 info.si_signo = signal; 466 else
481 info.si_errno = 0;
482 info.si_code = SEGV_MAPERR;
483 info.si_addr = (void __user *) location;
484 do_trap(pgm_int_code, signal,
485 "user address fault", regs, &info);
486 } else
487#endif 467#endif
488 if (signal) { 468 if (signal)
489 info.si_signo = signal; 469 do_trap(regs, signal, ILL_ILLOPC, "illegal operation");
490 info.si_errno = 0;
491 info.si_code = ILL_ILLOPC;
492 info.si_addr = (void __user *) location;
493 do_trap(pgm_int_code, signal,
494 "illegal operation", regs, &info);
495 }
496} 470}
497 471
498 472
499#ifdef CONFIG_MATHEMU 473#ifdef CONFIG_MATHEMU
500void specification_exception(struct pt_regs *regs, long pgm_int_code, 474void specification_exception(struct pt_regs *regs)
501 unsigned long trans_exc_code)
502{ 475{
503 __u8 opcode[6]; 476 __u8 opcode[6];
504 __u16 __user *location = NULL; 477 __u16 __user *location = NULL;
505 int signal = 0; 478 int signal = 0;
506 479
507 location = (__u16 __user *) get_psw_address(regs, pgm_int_code); 480 location = (__u16 __user *) get_psw_address(regs);
508 481
509 if (regs->psw.mask & PSW_MASK_PSTATE) { 482 if (regs->psw.mask & PSW_MASK_PSTATE) {
510 get_user(*((__u16 *) opcode), location); 483 get_user(*((__u16 *) opcode), location);
@@ -539,30 +512,21 @@ void specification_exception(struct pt_regs *regs, long pgm_int_code,
539 signal = SIGILL; 512 signal = SIGILL;
540 513
541 if (signal == SIGFPE) 514 if (signal == SIGFPE)
542 do_fp_trap(regs, location, 515 do_fp_trap(regs, current->thread.fp_regs.fpc);
543 current->thread.fp_regs.fpc, pgm_int_code); 516 else if (signal)
544 else if (signal) { 517 do_trap(regs, signal, ILL_ILLOPN, "specification exception");
545 siginfo_t info;
546 info.si_signo = signal;
547 info.si_errno = 0;
548 info.si_code = ILL_ILLOPN;
549 info.si_addr = location;
550 do_trap(pgm_int_code, signal,
551 "specification exception", regs, &info);
552 }
553} 518}
554#else 519#else
555DO_ERROR_INFO(specification_exception, SIGILL, ILL_ILLOPN, 520DO_ERROR_INFO(specification_exception, SIGILL, ILL_ILLOPN,
556 "specification exception"); 521 "specification exception");
557#endif 522#endif
558 523
559static void data_exception(struct pt_regs *regs, long pgm_int_code, 524static void data_exception(struct pt_regs *regs)
560 unsigned long trans_exc_code)
561{ 525{
562 __u16 __user *location; 526 __u16 __user *location;
563 int signal = 0; 527 int signal = 0;
564 528
565 location = get_psw_address(regs, pgm_int_code); 529 location = get_psw_address(regs);
566 530
567 if (MACHINE_HAS_IEEE) 531 if (MACHINE_HAS_IEEE)
568 asm volatile("stfpc %0" : "=m" (current->thread.fp_regs.fpc)); 532 asm volatile("stfpc %0" : "=m" (current->thread.fp_regs.fpc));
@@ -627,32 +591,18 @@ static void data_exception(struct pt_regs *regs, long pgm_int_code,
627 else 591 else
628 signal = SIGILL; 592 signal = SIGILL;
629 if (signal == SIGFPE) 593 if (signal == SIGFPE)
630 do_fp_trap(regs, location, 594 do_fp_trap(regs, current->thread.fp_regs.fpc);
631 current->thread.fp_regs.fpc, pgm_int_code); 595 else if (signal)
632 else if (signal) { 596 do_trap(regs, signal, ILL_ILLOPN, "data exception");
633 siginfo_t info;
634 info.si_signo = signal;
635 info.si_errno = 0;
636 info.si_code = ILL_ILLOPN;
637 info.si_addr = location;
638 do_trap(pgm_int_code, signal, "data exception", regs, &info);
639 }
640} 597}
641 598
642static void space_switch_exception(struct pt_regs *regs, long pgm_int_code, 599static void space_switch_exception(struct pt_regs *regs)
643 unsigned long trans_exc_code)
644{ 600{
645 siginfo_t info;
646
647 /* Set user psw back to home space mode. */ 601 /* Set user psw back to home space mode. */
648 if (regs->psw.mask & PSW_MASK_PSTATE) 602 if (regs->psw.mask & PSW_MASK_PSTATE)
649 regs->psw.mask |= PSW_ASC_HOME; 603 regs->psw.mask |= PSW_ASC_HOME;
650 /* Send SIGILL. */ 604 /* Send SIGILL. */
651 info.si_signo = SIGILL; 605 do_trap(regs, SIGILL, ILL_PRVOPC, "space switch event");
652 info.si_errno = 0;
653 info.si_code = ILL_PRVOPC;
654 info.si_addr = get_psw_address(regs, pgm_int_code);
655 do_trap(pgm_int_code, SIGILL, "space switch event", regs, &info);
656} 606}
657 607
658void __kprobes kernel_stack_overflow(struct pt_regs * regs) 608void __kprobes kernel_stack_overflow(struct pt_regs * regs)
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index a9a301866b3c..354dd39073ef 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -125,8 +125,7 @@ static inline int user_space_fault(unsigned long trans_exc_code)
125 return trans_exc_code != 3; 125 return trans_exc_code != 3;
126} 126}
127 127
128static inline void report_user_fault(struct pt_regs *regs, long int_code, 128static inline void report_user_fault(struct pt_regs *regs, long signr)
129 int signr, unsigned long address)
130{ 129{
131 if ((task_pid_nr(current) > 1) && !show_unhandled_signals) 130 if ((task_pid_nr(current) > 1) && !show_unhandled_signals)
132 return; 131 return;
@@ -134,10 +133,12 @@ static inline void report_user_fault(struct pt_regs *regs, long int_code,
134 return; 133 return;
135 if (!printk_ratelimit()) 134 if (!printk_ratelimit())
136 return; 135 return;
137 printk("User process fault: interruption code 0x%lX ", int_code); 136 printk(KERN_ALERT "User process fault: interruption code 0x%X ",
137 regs->int_code);
138 print_vma_addr(KERN_CONT "in ", regs->psw.addr & PSW_ADDR_INSN); 138 print_vma_addr(KERN_CONT "in ", regs->psw.addr & PSW_ADDR_INSN);
139 printk("\n"); 139 printk(KERN_CONT "\n");
140 printk("failing address: %lX\n", address); 140 printk(KERN_ALERT "failing address: %lX\n",
141 regs->int_parm_long & __FAIL_ADDR_MASK);
141 show_regs(regs); 142 show_regs(regs);
142} 143}
143 144
@@ -145,24 +146,18 @@ static inline void report_user_fault(struct pt_regs *regs, long int_code,
145 * Send SIGSEGV to task. This is an external routine 146 * Send SIGSEGV to task. This is an external routine
146 * to keep the stack usage of do_page_fault small. 147 * to keep the stack usage of do_page_fault small.
147 */ 148 */
148static noinline void do_sigsegv(struct pt_regs *regs, long int_code, 149static noinline void do_sigsegv(struct pt_regs *regs, int si_code)
149 int si_code, unsigned long trans_exc_code)
150{ 150{
151 struct siginfo si; 151 struct siginfo si;
152 unsigned long address;
153 152
154 address = trans_exc_code & __FAIL_ADDR_MASK; 153 report_user_fault(regs, SIGSEGV);
155 current->thread.prot_addr = address;
156 current->thread.trap_no = int_code;
157 report_user_fault(regs, int_code, SIGSEGV, address);
158 si.si_signo = SIGSEGV; 154 si.si_signo = SIGSEGV;
159 si.si_code = si_code; 155 si.si_code = si_code;
160 si.si_addr = (void __user *) address; 156 si.si_addr = (void __user *)(regs->int_parm_long & __FAIL_ADDR_MASK);
161 force_sig_info(SIGSEGV, &si, current); 157 force_sig_info(SIGSEGV, &si, current);
162} 158}
163 159
164static noinline void do_no_context(struct pt_regs *regs, long int_code, 160static noinline void do_no_context(struct pt_regs *regs)
165 unsigned long trans_exc_code)
166{ 161{
167 const struct exception_table_entry *fixup; 162 const struct exception_table_entry *fixup;
168 unsigned long address; 163 unsigned long address;
@@ -178,55 +173,48 @@ static noinline void do_no_context(struct pt_regs *regs, long int_code,
178 * Oops. The kernel tried to access some bad page. We'll have to 173 * Oops. The kernel tried to access some bad page. We'll have to
179 * terminate things with extreme prejudice. 174 * terminate things with extreme prejudice.
180 */ 175 */
181 address = trans_exc_code & __FAIL_ADDR_MASK; 176 address = regs->int_parm_long & __FAIL_ADDR_MASK;
182 if (!user_space_fault(trans_exc_code)) 177 if (!user_space_fault(regs->int_parm_long))
183 printk(KERN_ALERT "Unable to handle kernel pointer dereference" 178 printk(KERN_ALERT "Unable to handle kernel pointer dereference"
184 " at virtual kernel address %p\n", (void *)address); 179 " at virtual kernel address %p\n", (void *)address);
185 else 180 else
186 printk(KERN_ALERT "Unable to handle kernel paging request" 181 printk(KERN_ALERT "Unable to handle kernel paging request"
187 " at virtual user address %p\n", (void *)address); 182 " at virtual user address %p\n", (void *)address);
188 183
189 die("Oops", regs, int_code); 184 die(regs, "Oops");
190 do_exit(SIGKILL); 185 do_exit(SIGKILL);
191} 186}
192 187
193static noinline void do_low_address(struct pt_regs *regs, long int_code, 188static noinline void do_low_address(struct pt_regs *regs)
194 unsigned long trans_exc_code)
195{ 189{
196 /* Low-address protection hit in kernel mode means 190 /* Low-address protection hit in kernel mode means
197 NULL pointer write access in kernel mode. */ 191 NULL pointer write access in kernel mode. */
198 if (regs->psw.mask & PSW_MASK_PSTATE) { 192 if (regs->psw.mask & PSW_MASK_PSTATE) {
199 /* Low-address protection hit in user mode 'cannot happen'. */ 193 /* Low-address protection hit in user mode 'cannot happen'. */
200 die ("Low-address protection", regs, int_code); 194 die (regs, "Low-address protection");
201 do_exit(SIGKILL); 195 do_exit(SIGKILL);
202 } 196 }
203 197
204 do_no_context(regs, int_code, trans_exc_code); 198 do_no_context(regs);
205} 199}
206 200
207static noinline void do_sigbus(struct pt_regs *regs, long int_code, 201static noinline void do_sigbus(struct pt_regs *regs)
208 unsigned long trans_exc_code)
209{ 202{
210 struct task_struct *tsk = current; 203 struct task_struct *tsk = current;
211 unsigned long address;
212 struct siginfo si; 204 struct siginfo si;
213 205
214 /* 206 /*
215 * Send a sigbus, regardless of whether we were in kernel 207 * Send a sigbus, regardless of whether we were in kernel
216 * or user mode. 208 * or user mode.
217 */ 209 */
218 address = trans_exc_code & __FAIL_ADDR_MASK;
219 tsk->thread.prot_addr = address;
220 tsk->thread.trap_no = int_code;
221 si.si_signo = SIGBUS; 210 si.si_signo = SIGBUS;
222 si.si_errno = 0; 211 si.si_errno = 0;
223 si.si_code = BUS_ADRERR; 212 si.si_code = BUS_ADRERR;
224 si.si_addr = (void __user *) address; 213 si.si_addr = (void __user *)(regs->int_parm_long & __FAIL_ADDR_MASK);
225 force_sig_info(SIGBUS, &si, tsk); 214 force_sig_info(SIGBUS, &si, tsk);
226} 215}
227 216
228static noinline void do_fault_error(struct pt_regs *regs, long int_code, 217static noinline void do_fault_error(struct pt_regs *regs, int fault)
229 unsigned long trans_exc_code, int fault)
230{ 218{
231 int si_code; 219 int si_code;
232 220
@@ -238,24 +226,24 @@ static noinline void do_fault_error(struct pt_regs *regs, long int_code,
238 /* User mode accesses just cause a SIGSEGV */ 226 /* User mode accesses just cause a SIGSEGV */
239 si_code = (fault == VM_FAULT_BADMAP) ? 227 si_code = (fault == VM_FAULT_BADMAP) ?
240 SEGV_MAPERR : SEGV_ACCERR; 228 SEGV_MAPERR : SEGV_ACCERR;
241 do_sigsegv(regs, int_code, si_code, trans_exc_code); 229 do_sigsegv(regs, si_code);
242 return; 230 return;
243 } 231 }
244 case VM_FAULT_BADCONTEXT: 232 case VM_FAULT_BADCONTEXT:
245 do_no_context(regs, int_code, trans_exc_code); 233 do_no_context(regs);
246 break; 234 break;
247 default: /* fault & VM_FAULT_ERROR */ 235 default: /* fault & VM_FAULT_ERROR */
248 if (fault & VM_FAULT_OOM) { 236 if (fault & VM_FAULT_OOM) {
249 if (!(regs->psw.mask & PSW_MASK_PSTATE)) 237 if (!(regs->psw.mask & PSW_MASK_PSTATE))
250 do_no_context(regs, int_code, trans_exc_code); 238 do_no_context(regs);
251 else 239 else
252 pagefault_out_of_memory(); 240 pagefault_out_of_memory();
253 } else if (fault & VM_FAULT_SIGBUS) { 241 } else if (fault & VM_FAULT_SIGBUS) {
254 /* Kernel mode? Handle exceptions or die */ 242 /* Kernel mode? Handle exceptions or die */
255 if (!(regs->psw.mask & PSW_MASK_PSTATE)) 243 if (!(regs->psw.mask & PSW_MASK_PSTATE))
256 do_no_context(regs, int_code, trans_exc_code); 244 do_no_context(regs);
257 else 245 else
258 do_sigbus(regs, int_code, trans_exc_code); 246 do_sigbus(regs);
259 } else 247 } else
260 BUG(); 248 BUG();
261 break; 249 break;
@@ -273,12 +261,12 @@ static noinline void do_fault_error(struct pt_regs *regs, long int_code,
273 * 11 Page translation -> Not present (nullification) 261 * 11 Page translation -> Not present (nullification)
274 * 3b Region third trans. -> Not present (nullification) 262 * 3b Region third trans. -> Not present (nullification)
275 */ 263 */
276static inline int do_exception(struct pt_regs *regs, int access, 264static inline int do_exception(struct pt_regs *regs, int access)
277 unsigned long trans_exc_code)
278{ 265{
279 struct task_struct *tsk; 266 struct task_struct *tsk;
280 struct mm_struct *mm; 267 struct mm_struct *mm;
281 struct vm_area_struct *vma; 268 struct vm_area_struct *vma;
269 unsigned long trans_exc_code;
282 unsigned long address; 270 unsigned long address;
283 unsigned int flags; 271 unsigned int flags;
284 int fault; 272 int fault;
@@ -288,6 +276,7 @@ static inline int do_exception(struct pt_regs *regs, int access,
288 276
289 tsk = current; 277 tsk = current;
290 mm = tsk->mm; 278 mm = tsk->mm;
279 trans_exc_code = regs->int_parm_long;
291 280
292 /* 281 /*
293 * Verify that the fault happened in user space, that 282 * Verify that the fault happened in user space, that
@@ -387,45 +376,46 @@ out:
387 return fault; 376 return fault;
388} 377}
389 378
390void __kprobes do_protection_exception(struct pt_regs *regs, long pgm_int_code, 379void __kprobes do_protection_exception(struct pt_regs *regs)
391 unsigned long trans_exc_code)
392{ 380{
381 unsigned long trans_exc_code;
393 int fault; 382 int fault;
394 383
384 trans_exc_code = regs->int_parm_long;
395 /* Protection exception is suppressing, decrement psw address. */ 385 /* Protection exception is suppressing, decrement psw address. */
396 regs->psw.addr = __rewind_psw(regs->psw, pgm_int_code >> 16); 386 regs->psw.addr = __rewind_psw(regs->psw, regs->int_code >> 16);
397 /* 387 /*
398 * Check for low-address protection. This needs to be treated 388 * Check for low-address protection. This needs to be treated
399 * as a special case because the translation exception code 389 * as a special case because the translation exception code
400 * field is not guaranteed to contain valid data in this case. 390 * field is not guaranteed to contain valid data in this case.
401 */ 391 */
402 if (unlikely(!(trans_exc_code & 4))) { 392 if (unlikely(!(trans_exc_code & 4))) {
403 do_low_address(regs, pgm_int_code, trans_exc_code); 393 do_low_address(regs);
404 return; 394 return;
405 } 395 }
406 fault = do_exception(regs, VM_WRITE, trans_exc_code); 396 fault = do_exception(regs, VM_WRITE);
407 if (unlikely(fault)) 397 if (unlikely(fault))
408 do_fault_error(regs, 4, trans_exc_code, fault); 398 do_fault_error(regs, fault);
409} 399}
410 400
411void __kprobes do_dat_exception(struct pt_regs *regs, long pgm_int_code, 401void __kprobes do_dat_exception(struct pt_regs *regs)
412 unsigned long trans_exc_code)
413{ 402{
414 int access, fault; 403 int access, fault;
415 404
416 access = VM_READ | VM_EXEC | VM_WRITE; 405 access = VM_READ | VM_EXEC | VM_WRITE;
417 fault = do_exception(regs, access, trans_exc_code); 406 fault = do_exception(regs, access);
418 if (unlikely(fault)) 407 if (unlikely(fault))
419 do_fault_error(regs, pgm_int_code & 255, trans_exc_code, fault); 408 do_fault_error(regs, fault);
420} 409}
421 410
422#ifdef CONFIG_64BIT 411#ifdef CONFIG_64BIT
423void __kprobes do_asce_exception(struct pt_regs *regs, long pgm_int_code, 412void __kprobes do_asce_exception(struct pt_regs *regs)
424 unsigned long trans_exc_code)
425{ 413{
426 struct mm_struct *mm = current->mm; 414 struct mm_struct *mm = current->mm;
427 struct vm_area_struct *vma; 415 struct vm_area_struct *vma;
416 unsigned long trans_exc_code;
428 417
418 trans_exc_code = regs->int_parm_long;
429 if (unlikely(!user_space_fault(trans_exc_code) || in_atomic() || !mm)) 419 if (unlikely(!user_space_fault(trans_exc_code) || in_atomic() || !mm))
430 goto no_context; 420 goto no_context;
431 421
@@ -440,12 +430,12 @@ void __kprobes do_asce_exception(struct pt_regs *regs, long pgm_int_code,
440 430
441 /* User mode accesses just cause a SIGSEGV */ 431 /* User mode accesses just cause a SIGSEGV */
442 if (regs->psw.mask & PSW_MASK_PSTATE) { 432 if (regs->psw.mask & PSW_MASK_PSTATE) {
443 do_sigsegv(regs, pgm_int_code, SEGV_MAPERR, trans_exc_code); 433 do_sigsegv(regs, SEGV_MAPERR);
444 return; 434 return;
445 } 435 }
446 436
447no_context: 437no_context:
448 do_no_context(regs, pgm_int_code, trans_exc_code); 438 do_no_context(regs);
449} 439}
450#endif 440#endif
451 441
@@ -459,14 +449,15 @@ int __handle_fault(unsigned long uaddr, unsigned long pgm_int_code, int write)
459 regs.psw.mask |= PSW_MASK_IO | PSW_MASK_EXT; 449 regs.psw.mask |= PSW_MASK_IO | PSW_MASK_EXT;
460 regs.psw.addr = (unsigned long) __builtin_return_address(0); 450 regs.psw.addr = (unsigned long) __builtin_return_address(0);
461 regs.psw.addr |= PSW_ADDR_AMODE; 451 regs.psw.addr |= PSW_ADDR_AMODE;
462 uaddr &= PAGE_MASK; 452 regs.int_code = pgm_int_code;
453 regs.int_parm_long = (uaddr & PAGE_MASK) | 2;
463 access = write ? VM_WRITE : VM_READ; 454 access = write ? VM_WRITE : VM_READ;
464 fault = do_exception(&regs, access, uaddr | 2); 455 fault = do_exception(&regs, access);
465 if (unlikely(fault)) { 456 if (unlikely(fault)) {
466 if (fault & VM_FAULT_OOM) 457 if (fault & VM_FAULT_OOM)
467 return -EFAULT; 458 return -EFAULT;
468 else if (fault & VM_FAULT_SIGBUS) 459 else if (fault & VM_FAULT_SIGBUS)
469 do_sigbus(&regs, pgm_int_code, uaddr); 460 do_sigbus(&regs);
470 } 461 }
471 return fault ? -EFAULT : 0; 462 return fault ? -EFAULT : 0;
472} 463}
@@ -509,7 +500,7 @@ int pfault_init(void)
509 .reserved = __PF_RES_FIELD }; 500 .reserved = __PF_RES_FIELD };
510 int rc; 501 int rc;
511 502
512 if (!MACHINE_IS_VM || pfault_disable) 503 if (pfault_disable)
513 return -1; 504 return -1;
514 asm volatile( 505 asm volatile(
515 " diag %1,%0,0x258\n" 506 " diag %1,%0,0x258\n"
@@ -530,7 +521,7 @@ void pfault_fini(void)
530 .refversn = 2, 521 .refversn = 2,
531 }; 522 };
532 523
533 if (!MACHINE_IS_VM || pfault_disable) 524 if (pfault_disable)
534 return; 525 return;
535 asm volatile( 526 asm volatile(
536 " diag %0,0,0x258\n" 527 " diag %0,0,0x258\n"
@@ -643,8 +634,6 @@ static int __init pfault_irq_init(void)
643{ 634{
644 int rc; 635 int rc;
645 636
646 if (!MACHINE_IS_VM)
647 return 0;
648 rc = register_external_interrupt(0x2603, pfault_interrupt); 637 rc = register_external_interrupt(0x2603, pfault_interrupt);
649 if (rc) 638 if (rc)
650 goto out_extint; 639 goto out_extint;
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c
index d4b9fb4d0042..5d633019d8f3 100644
--- a/arch/s390/mm/init.c
+++ b/arch/s390/mm/init.c
@@ -93,18 +93,22 @@ static unsigned long setup_zero_pages(void)
93void __init paging_init(void) 93void __init paging_init(void)
94{ 94{
95 unsigned long max_zone_pfns[MAX_NR_ZONES]; 95 unsigned long max_zone_pfns[MAX_NR_ZONES];
96 unsigned long pgd_type; 96 unsigned long pgd_type, asce_bits;
97 97
98 init_mm.pgd = swapper_pg_dir; 98 init_mm.pgd = swapper_pg_dir;
99 S390_lowcore.kernel_asce = __pa(init_mm.pgd) & PAGE_MASK;
100#ifdef CONFIG_64BIT 99#ifdef CONFIG_64BIT
101 /* A three level page table (4TB) is enough for the kernel space. */ 100 if (VMALLOC_END > (1UL << 42)) {
102 S390_lowcore.kernel_asce |= _ASCE_TYPE_REGION3 | _ASCE_TABLE_LENGTH; 101 asce_bits = _ASCE_TYPE_REGION2 | _ASCE_TABLE_LENGTH;
103 pgd_type = _REGION3_ENTRY_EMPTY; 102 pgd_type = _REGION2_ENTRY_EMPTY;
103 } else {
104 asce_bits = _ASCE_TYPE_REGION3 | _ASCE_TABLE_LENGTH;
105 pgd_type = _REGION3_ENTRY_EMPTY;
106 }
104#else 107#else
105 S390_lowcore.kernel_asce |= _ASCE_TABLE_LENGTH; 108 asce_bits = _ASCE_TABLE_LENGTH;
106 pgd_type = _SEGMENT_ENTRY_EMPTY; 109 pgd_type = _SEGMENT_ENTRY_EMPTY;
107#endif 110#endif
111 S390_lowcore.kernel_asce = (__pa(init_mm.pgd) & PAGE_MASK) | asce_bits;
108 clear_table((unsigned long *) init_mm.pgd, pgd_type, 112 clear_table((unsigned long *) init_mm.pgd, pgd_type,
109 sizeof(unsigned long)*2048); 113 sizeof(unsigned long)*2048);
110 vmem_map_init(); 114 vmem_map_init();
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c
index 301c84d3b542..9a4d02f64f16 100644
--- a/arch/s390/mm/pgtable.c
+++ b/arch/s390/mm/pgtable.c
@@ -33,17 +33,6 @@
33#define FRAG_MASK 0x03 33#define FRAG_MASK 0x03
34#endif 34#endif
35 35
36unsigned long VMALLOC_START = VMALLOC_END - VMALLOC_SIZE;
37EXPORT_SYMBOL(VMALLOC_START);
38
39static int __init parse_vmalloc(char *arg)
40{
41 if (!arg)
42 return -EINVAL;
43 VMALLOC_START = (VMALLOC_END - memparse(arg, &arg)) & PAGE_MASK;
44 return 0;
45}
46early_param("vmalloc", parse_vmalloc);
47 36
48unsigned long *crst_table_alloc(struct mm_struct *mm) 37unsigned long *crst_table_alloc(struct mm_struct *mm)
49{ 38{
@@ -267,7 +256,10 @@ static int gmap_alloc_table(struct gmap *gmap,
267 struct page *page; 256 struct page *page;
268 unsigned long *new; 257 unsigned long *new;
269 258
259 /* since we dont free the gmap table until gmap_free we can unlock */
260 spin_unlock(&gmap->mm->page_table_lock);
270 page = alloc_pages(GFP_KERNEL, ALLOC_ORDER); 261 page = alloc_pages(GFP_KERNEL, ALLOC_ORDER);
262 spin_lock(&gmap->mm->page_table_lock);
271 if (!page) 263 if (!page)
272 return -ENOMEM; 264 return -ENOMEM;
273 new = (unsigned long *) page_to_phys(page); 265 new = (unsigned long *) page_to_phys(page);